/* ==========================================================================
   App UI components (dashboard, players, forms, tables). Builds on the tokens in
   app.css ("Firouzeh & Ink"). RTL-first logical properties; transform/opacity
   motion only; every interactive target >= 44px.
   ========================================================================== */

/* icons follow the text they sit in (~1.2em, 14-22px); components that need a fixed size set it */
.ic { inline-size: clamp(14px, 1.2em, 22px); block-size: clamp(14px, 1.2em, 22px); flex: none; }
.ic.sm, .tag .ic, small .ic { stroke-width: 2; }
.hide-sm { display: none !important; }
@media (min-width: 760px) { .hide-sm { display: inline-flex !important; } .show-sm { display: none !important; } }
.muted { color: var(--ink-2); }
.small { font-size: var(--fs-sm); }
.center { text-align: center; }
.stack { display: grid; gap: 12px; align-content: start; }
.stack-lg { display: grid; gap: 24px; align-content: start; }
.row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.row.between { justify-content: space-between; }
.grow { flex: 1 1 auto; }
.num { font-variant-numeric: tabular-nums; }
[hidden] { display: none !important; }

/* nav additions: menus (desktop popover, phone bottom sheet), grouped lists -------------------------------- */
.nav-links a.is-active { color: var(--ink); }
.menu { position: relative; }
.menu > summary { list-style: none; cursor: pointer; }
.menu > summary::-webkit-details-marker { display: none; }
.navmenu { display: inline-block; }
@media (min-width: 900px) { .navmenu { display: none; } .usermenu .menu-nav { display: none; } }
.menu[open] > summary.icon-btn { background: var(--tint); color: var(--indigo); }
/* desktop: an anchored popover that scales out of its trigger (top-left in RTL) */
.menu-pop { position: absolute; inset-inline-end: 0; inset-block-start: calc(100% + 8px); z-index: 60; inline-size: 264px; display: grid; gap: 8px;
  padding: 8px; border-radius: var(--r-md); background: var(--mat-card); -webkit-backdrop-filter: var(--mat-blur); backdrop-filter: var(--mat-blur);
  box-shadow: var(--e2); font-size: var(--fs-sm); transform-origin: top left; }
html[data-motion="2"] .menu[open] .menu-pop, html[data-motion="3"] .menu[open] .menu-pop, html[data-motion="1"] .menu[open] .menu-pop { animation: menu-in var(--dur-2) var(--spring); }
@keyframes menu-in { from { opacity: 0; transform: scale(0.94); } }
.sheet-grabber { display: none; }
.usermenu-name { display: flex; gap: 10px; align-items: center; padding: 6px 8px 4px; font-weight: 650; line-height: 1.45; }
.usermenu-name > span:last-child { display: grid; }
.usermenu-name small { font-weight: 500; color: var(--ink-2); font-size: var(--fs-xs); justify-self: start; }
.um-avatar { inline-size: 36px; block-size: 36px; border-radius: 50%; display: grid; place-items: center; flex: none;
  background: linear-gradient(135deg, var(--brand-a), var(--brand-b)); color: #fff; }
.um-avatar .ic { inline-size: 18px; block-size: 18px; }

/* grouped list (iOS inset-grouped): rows with an icon, inset separators, no outer border */
.glist { display: grid; margin: 0; padding: 0; list-style: none; border-radius: var(--r-md); background: var(--card); overflow: hidden; }
.menu-pop .glist { background: color-mix(in srgb, var(--card) 70%, transparent); }
.glist > a, .glist > button, .glist > li > a, .glist > li > button { position: relative; display: flex; gap: 12px; align-items: center; inline-size: 100%;
  min-block-size: 44px; padding: 8px 12px; border: 0; background: none; text-align: start; text-decoration: none; color: var(--ink);
  font: inherit; font-weight: 500; transition: background-color var(--dur-1) var(--ease-std); }
.glist > :not(:first-child)::before, .glist > li:not(:first-child) > :is(a, button)::before { content: ""; position: absolute; inset-block-start: 0; inset-inline: 44px 0;
  block-size: 0.5px; background: var(--sep); }
.glist > li { position: relative; }
.glist .ic { inline-size: 20px; block-size: 20px; color: var(--indigo); flex: none; }
.glist > :is(a, button):active, .glist > li > :is(a, button):active { background: color-mix(in srgb, var(--ink) 8%, transparent); }
@media (hover: hover) and (pointer: fine) { .glist > :is(a, button):hover, .glist > li > :is(a, button):hover { background: color-mix(in srgb, var(--ink) 5%, transparent); } }
.glist .danger, .glist .danger .ic { color: var(--bad); }
.glist-toggle { justify-content: flex-start; }
.glist-toggle > span { flex: 1; }
/* site language (فارسی / English, core.middleware.UILanguageMiddleware): the other language's name, in its own script */
.lang-switch button > span { flex: 1; }
.lang-switch small { font-size: var(--fs-xs); color: var(--ink-2); font-weight: 500; }
.lang-switch-foot { margin: 0; }
.lang-switch-foot button { display: inline-flex; gap: 6px; align-items: center; min-block-size: 36px; padding: 0; border: 0; background: none;
  font: inherit; color: var(--ink-2); cursor: pointer; }
.lang-switch-foot .ic { inline-size: 16px; block-size: 16px; }
@media (hover: hover) and (pointer: fine) { .lang-switch-foot button:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; } }
/* switch (iOS): green-free, accent track */
.switch { position: relative; inline-size: 44px; block-size: 26px; border-radius: 999px; background: color-mix(in srgb, var(--ink) 16%, transparent); flex: none;
  transition: background-color var(--dur-2) var(--ease-std); }
.switch::after { content: ""; position: absolute; inset-block-start: 2px; inset-inline-start: 2px; inline-size: 22px; block-size: 22px; border-radius: 50%; background: #fff;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.25); transition: transform var(--dur-3) var(--spring); }
[aria-checked="true"] > .switch { background: var(--indigo); }
[aria-checked="true"] > .switch::after { transform: translateX(-18px); }
[dir="ltr"] [aria-checked="true"] > .switch::after { transform: translateX(18px); }

/* phones: the menu is a bottom sheet over a dimming scrim (the scrim is the <details> itself, so a tap closes it) */
@media (max-width: 899px) {
  .menu[open]::before { content: ""; position: fixed; inset: 0; z-index: 70; background: var(--scrim); }
  html[data-motion]:not([data-motion="0"]) .menu[open]::before { animation: scrim-in var(--dur-3) var(--ease-std); }
  .menu-pop { position: fixed; z-index: 71; inset-inline: 8px; inset-block: auto calc(8px + var(--safe-b)); inline-size: auto;
    max-block-size: calc(100dvh - var(--safe-t) - 56px); overflow-y: auto; overscroll-behavior: contain; padding: 6px 12px 12px; gap: 12px;
    border-radius: var(--r-xl); background: var(--paper); -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: var(--e3);
    font-size: var(--fs-base); transform-origin: bottom center; }
  .menu-pop .glist { background: var(--card); }
  .glist > a, .glist > button { min-block-size: 50px; padding-inline: 14px; }
  .glist > :not(:first-child)::before { inset-inline-start: 48px; }
  .sheet-grabber { display: block; justify-self: center; inline-size: 36px; block-size: 5px; border-radius: 3px; background: color-mix(in srgb, var(--ink) 22%, transparent); margin-block: 2px 0; }
  html[data-motion="2"] .menu[open] .menu-pop, html[data-motion="3"] .menu[open] .menu-pop, html[data-motion="1"] .menu[open] .menu-pop { animation: sheet-rise var(--dur-3) var(--spring); }
  body:has(.menu[open]) { overflow: hidden; }
}
@keyframes sheet-rise { from { transform: translateY(105%); } }
@keyframes scrim-in { from { opacity: 0; } }
.hide-xs { display: none !important; }
@media (min-width: 600px) { .hide-xs { display: inline-grid !important; } }

/* toasts ------------------------------------------------------------------- */
.toasts { display: grid; gap: 8px; margin-block: 12px; }
.toast { padding: 12px 16px; border-radius: var(--r-md); font-size: var(--fs-sm); background: var(--card); }

/* bottom tab bar (signed-in, phones): a floating glass capsule (iOS 26 / Telegram). The current tab sits under a glass
   "lens" that slides between tabs on a spring; drag a finger along the bar and the lens follows it, magnified, and letting
   go opens the tab under it (ui.js). Without JS the current tab simply wears the lens's tint. --tabbar-h is the space the
   bar takes from the bottom of the screen (62px capsule + 10px float), which everything that floats above it uses. */
.tabbar { position: fixed; z-index: 55; inset-inline: 0; inset-block-end: calc(10px + var(--safe-b)); margin-inline: auto;
  inline-size: min(100% - 24px - var(--safe-l) - var(--safe-r), 440px); display: grid; grid-template-columns: repeat(5, 1fr); padding: 5px;
  border-radius: 999px; background: color-mix(in srgb, var(--paper) 68%, transparent);
  -webkit-backdrop-filter: blur(24px) saturate(190%); backdrop-filter: blur(24px) saturate(190%);
  box-shadow: 0 0 0 0.5px color-mix(in srgb, var(--ink) 12%, transparent), 0 12px 32px -12px rgb(0 0 0 / 0.38),
    inset 0 1px 0 rgb(255 255 255 / 0.42), inset 0 -1px 0 rgb(0 0 0 / 0.04);
  touch-action: pan-y; -webkit-user-select: none; user-select: none; }
.tabbar a { position: relative; z-index: 1; display: grid; justify-items: center; align-content: center; gap: 1px; min-block-size: 52px;
  border-radius: 999px; text-decoration: none; color: var(--ink-2); font-size: 0.66rem; font-weight: 650; line-height: 1.25; letter-spacing: 0.01em;
  -webkit-tap-highlight-color: transparent; transition: color var(--dur-2) var(--ease-std); }
.tabbar a .ic { inline-size: 24px; block-size: 24px; stroke-width: 1.75; transition: transform var(--dur-2) var(--spring); }
/* outline normally, solid when selected (the "-on" twin, tools/icons/build_sprite.py ON), as iOS tab bars do */
.tabbar a .ic-on { display: none; }
.tabbar a:is([aria-current="page"], [aria-expanded="true"], .is-target) .ic:not(.ic-on) { display: none; }
.tabbar a:is([aria-current="page"], [aria-expanded="true"], .is-target) .ic-on { display: block; }
.tabbar a:active .ic { transform: scale(0.86); transition-duration: var(--dur-1); }
.tabbar a.is-active, .tabbar a[aria-current="page"], .tabbar a.is-target { color: var(--indigo); }
.tabbar a[aria-current="page"] .ic, .tabbar a.is-target .ic { stroke-width: 2.2; }
.tabbar a:focus-visible { outline: 2px solid var(--indigo); outline-offset: -3px; }
/* no JS yet (or no lens): the current tab carries the tint itself */
.tabbar:not(.has-lens) a[aria-current="page"] { background: color-mix(in srgb, var(--indigo) 13%, transparent); }
.tab-lens { position: absolute; inset-block: 5px; left: 0; inline-size: var(--lens-w, 0px); border-radius: 999px; pointer-events: none; opacity: 0;
  background: color-mix(in srgb, var(--indigo) 13%, transparent);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.5), inset 0 0 0 0.5px color-mix(in srgb, var(--indigo) 22%, transparent);
  transform: translateX(var(--lens-x, 0px)) scale(var(--lens-s, 1));
  transition: transform 460ms var(--spring), inline-size 460ms var(--spring), opacity var(--dur-2) var(--ease-std); }
.tabbar.has-lens .tab-lens { opacity: 1; }
/* dragging: the lens is glued to the finger (no transition) and swells like a drop of glass */
.tabbar.is-dragging .tab-lens { --lens-s: 1.12; transition: transform 90ms linear, inline-size var(--dur-2) var(--ease-std);
  background: color-mix(in srgb, var(--indigo) 9%, rgb(255 255 255 / 0.35));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.65), 0 6px 18px -6px rgb(0 0 0 / 0.3), inset 0 0 0 0.5px color-mix(in srgb, var(--indigo) 30%, transparent); }
.tabbar.is-dragging a .ic { transition-duration: var(--dur-1); }
.tabbar.is-dragging a.is-target .ic { transform: scale(1.1); }
html[data-motion="0"] .tab-lens { transition: opacity var(--dur-1) linear; }
@media (prefers-reduced-transparency: reduce) { .tabbar { background: var(--card); -webkit-backdrop-filter: none; backdrop-filter: none; } }
@media (prefers-contrast: more) { .tabbar { box-shadow: 0 0 0 1.5px var(--ink); } }
body.has-tabbar:has(> .tabbar) { padding-block-end: calc(var(--tabbar-h) + var(--safe-b) + 8px); }
@media (min-width: 900px) { .tabbar { display: none; } body.has-tabbar:has(> .tabbar) { padding-block-end: 0; } }
/* phones: the tab bar's «من» opens the account menu as the bottom sheet (ui.js, base.html #site-menu), so the header's
   profile button steps aside: one way in. Desktop (no tab bar) keeps the header button. */
@media (max-width: 899px) { body:has(> .tabbar) .usermenu > summary { display: none; } }
.tabbar a[aria-expanded="true"] { color: var(--indigo); }
.tabbar a[aria-expanded="true"] .ic { stroke-width: 2.2; }

/* footer: small, quiet, Apple-style columns -------------------------------------------------------------------- */
.site-footer { padding-block: 40px calc(28px + var(--safe-b)); font-size: var(--fs-xs); color: var(--ink-2); }
.footer-grid { display: grid; gap: 24px; grid-template-columns: 1fr; border-block-start: 0.5px solid var(--sep); padding-block-start: 24px; }
.footer-grid nav { display: grid; gap: 0; align-content: start; }
.footer-grid h2 { font-size: var(--fs-xs); font-weight: 650; color: var(--ink); margin-block-end: 6px; font-family: var(--f-body); }
.footer-grid nav a { color: var(--ink-2); text-decoration: none; min-block-size: 36px; display: inline-flex; align-items: center; justify-self: start; }
@media (hover: hover) and (pointer: fine) { .footer-grid nav a:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; } }
.footer-grid .fine { border: 0; padding: 0; font-size: var(--fs-xs); line-height: 1.75; max-inline-size: 46ch; }
.footer-grid .foot-note { margin-block-start: 8px; }
.enamad { display: inline-grid; place-items: center; min-inline-size: 96px; min-block-size: 96px; padding: 6px; border-radius: 12px;
  background: #fff; border: 0.5px solid var(--sep); }
.enamad img { display: block; max-inline-size: 120px; block-size: auto; }
.enamad.is-text img { display: none; }
.enamad.is-text a { display: grid; place-items: center; min-block-size: 84px; max-inline-size: 110px; text-align: center; color: #1a3d7c;
  font-size: var(--fs-xs); font-weight: 650; line-height: 1.6; text-decoration: none; }
.enamad.is-text a::after { content: "نماد اعتماد الکترونیکی (اینماد)"; }
.foot-contact { font-style: normal; display: grid; gap: 4px; line-height: 1.7; margin-block-end: 14px; }
.foot-contact a { color: var(--ink-2); text-underline-offset: 3px; }
@media (max-width: 759px) { .footer-grid { grid-template-columns: 1fr 1fr; } .footer-grid > div { grid-column: 1 / -1; } }
@media (min-width: 760px) { .footer-grid { grid-template-columns: 2fr 1fr 1fr 1fr; } }
/* the company's social profiles under the footer note (core/_social_links.html): small round buttons, 44px targets */
.foot-social-wrap { margin-block-start: 18px; }
.foot-social-wrap h2 { margin-block-end: 8px; }
.foot-social { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.foot-social a { display: grid; place-items: center; inline-size: 44px; block-size: 44px; border-radius: 50%; color: var(--ink-2);
  background: color-mix(in srgb, var(--ink) 6%, transparent); -webkit-tap-highlight-color: transparent;
  transition: color var(--dur-2) var(--ease-std), background-color var(--dur-2) var(--ease-std), transform var(--dur-2) var(--ease-std); }
.foot-social .ic { inline-size: 20px; block-size: 20px; }
.foot-social a:focus-visible { outline: 2px solid var(--indigo); outline-offset: 2px; }
.foot-social a:active { transform: scale(0.94); }
@media (hover: hover) and (pointer: fine) { .foot-social a:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 11%, transparent); } }

/* pages & cards -------------------------------------------------------------- */
.page { padding-block: 20px 56px; }
.page-head { display: grid; gap: 6px; margin-block-end: 20px; }
.page-head h1 { font-size: var(--fs-h1); }
.page-head p { color: var(--ink-2); max-inline-size: 60ch; }
.crumbs { display: flex; flex-wrap: wrap; gap: 6px; color: var(--ink-2); font-size: var(--fs-sm); }
.crumbs a { color: inherit; }
.crumbs ol { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 6px; margin: 0; padding: 0; list-style: none; min-inline-size: 0; }
.crumbs li { display: inline-flex; align-items: center; gap: 6px; min-inline-size: 0; }
.crumbs li + li::before { content: "/"; opacity: 0.55; }
.crumbs a { position: relative; display: inline-flex; align-items: center; min-block-size: 32px; text-decoration-color: color-mix(in srgb, currentColor 35%, transparent); }
.crumbs a::before { content: ""; position: absolute; inset: -6px -4px; }
.crumbs [aria-current] { color: var(--ink); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-inline-size: 36ch; }
.lesson-hero .crumbs [aria-current], .intro-hero .crumbs [aria-current] { color: inherit; }
.card { background: var(--card); border: 1px solid var(--hair); border-radius: var(--radius); padding: 16px; }
@media (min-width: 760px) { .card { padding: 18px 20px; } }
.card h2 { font-size: var(--fs-md); margin-block-end: 8px; }
.card.tight { padding: 12px 14px; }
.card.link { text-decoration: none; display: grid; gap: 6px; transition: transform 180ms var(--ease-out), border-color 180ms; }
@media (hover: hover) and (pointer: fine) { .card.link:hover { transform: translateY(-2px); border-color: var(--indigo); } }
.grid { display: grid; gap: 12px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .grid.g2, .grid.g3, .grid.g4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 980px) { .grid.g3 { grid-template-columns: repeat(3, 1fr); } .grid.g4 { grid-template-columns: repeat(4, 1fr); } }
.section-title { font-size: var(--fs-lg); margin-block: 6px 10px; display: flex; gap: 8px; align-items: center; }

/* badges, pills, filters ------------------------------------------------------ */
.lvl { display: inline-flex; align-items: center; justify-content: center; min-inline-size: 30px; padding: 0 6px; border-radius: var(--r-xs);
  font: 700 var(--fs-2xs)/1.75 var(--f-display); letter-spacing: 0.02em; background: var(--paper-2); color: var(--ink); direction: ltr; }
.lvl.A1, .lvl.A2 { background: color-mix(in srgb, var(--teal-deco) 18%, var(--card)); }
.lvl.B1, .lvl.B2 { background: color-mix(in srgb, var(--indigo) 16%, var(--card)); }
.lvl.C1, .lvl.C2 { background: color-mix(in srgb, var(--saffron) 30%, var(--card)); }
.tag { display: inline-flex; gap: 4px; align-items: center; padding: 1px 8px; border-radius: 999px; font-size: var(--fs-xs); font-weight: 600; line-height: 1.7;
  background: var(--paper-2); color: var(--ink-2); }
.tag.premium { background: color-mix(in srgb, var(--saffron) 28%, var(--card)); color: var(--ink); }
.tag.ok { background: color-mix(in srgb, var(--ok) 16%, var(--card)); color: var(--ok); }
.tag.bad { background: color-mix(in srgb, var(--bad) 14%, var(--card)); color: var(--bad); }
.tag .ic { inline-size: 13px; block-size: 13px; }
.filters { display: flex; flex-wrap: wrap; gap: 6px; margin-block-end: 16px; }
.pill { position: relative; display: inline-flex; align-items: center; min-block-size: var(--ctl-sm); padding-inline: 12px; border-radius: 999px; border: 1px solid var(--hair);
  background: var(--card); text-decoration: none; font-weight: 600; font-size: var(--fs-sm); }
@media (hover: hover) and (pointer: fine) { .pill:hover { border-color: var(--indigo); } }
.pill.on { background: var(--ink); color: var(--paper); border-color: var(--ink); }

/* forms ------------------------------------------------------------------------ */
.field { display: grid; gap: 4px; }
.field > label, .field > .label { font-weight: 600; font-size: var(--fs-sm); }
.help, .helptext { color: var(--ink-2); font-size: var(--fs-xs); }
input[type="text"], input[type="tel"], input[type="email"], input[type="number"], input[type="search"], input[type="date"],
input[type="datetime-local"], input[type="password"], .input {
  font: inherit; color: var(--ink); background: var(--card); border: 1px solid var(--hair); border-radius: var(--r-md); padding: 7px 12px;
  min-block-size: var(--ctl); inline-size: 100%; transition: border-color 160ms, box-shadow 160ms;
}
input:focus-visible, .input:focus-visible { outline: 2px solid transparent; box-shadow: 0 0 0 3px color-mix(in srgb, var(--indigo) 32%, transparent); border-color: var(--indigo); }
.errorlist { list-style: none; margin: 0; padding: 0; color: var(--bad); font-size: var(--fs-sm); font-weight: 600; }
.choices { display: flex; flex-wrap: wrap; gap: 6px; }
.choices label, .choice { display: inline-flex; gap: 8px; align-items: center; padding: 6px 12px; border: 1px solid var(--hair); border-radius: var(--r-md);
  cursor: pointer; min-block-size: var(--ctl); background: var(--card); font-size: var(--fs-sm); }
.choices label:has(input:checked), .choice:has(input:checked) { border-color: var(--indigo); background: color-mix(in srgb, var(--indigo) 8%, var(--card)); }
.choices ul, .choices div { display: contents; }
.form-grid { display: grid; gap: 14px; }
.checkbox { display: flex; gap: 10px; align-items: flex-start; }
.checkbox input { inline-size: 18px; block-size: 18px; margin-block-start: 4px; }

/* auth ----------------------------------------------------------------------- */
.auth-wrap { min-block-size: calc(100dvh - 160px); display: grid; place-items: center; padding: 24px var(--gutter); }
.auth-card { inline-size: min(100%, 400px); background: var(--card); border: 1px solid var(--hair); border-radius: var(--r-xl); padding: 24px;
  box-shadow: var(--e2); display: grid; gap: 14px; }
.auth-card h1 { font-size: var(--fs-xl); }
.otp-input { text-align: center; font: 700 1.5rem/1 var(--f-display) !important; letter-spacing: 0.35em !important; direction: ltr; }
.devcode { background: color-mix(in srgb, var(--saffron) 25%, var(--card)); border-radius: var(--r-sm); padding: 6px 10px; font-size: var(--fs-sm); }
.resend { display: flex; gap: 8px; align-items: center; color: var(--ink-2); font-size: var(--fs-sm); flex-wrap: wrap; }
.linkbtn { background: none; border: 0; color: var(--indigo); font-weight: 600; padding: 6px 4px; min-block-size: 44px; cursor: pointer; }
.linkbtn[disabled] { color: var(--ink-2); cursor: default; }

/* dashboard ------------------------------------------------------------------- */
.dash { display: grid; gap: 12px; grid-template-columns: 1fr; }
@media (min-width: 980px) { .dash { grid-template-columns: 2fr 1fr; } }
.hello { display: flex; flex-wrap: wrap; gap: 14px 24px; align-items: center; justify-content: space-between; }
.hello h1 { font-size: var(--fs-h1); }
.statrow { display: flex; flex-wrap: wrap; gap: 8px; }
.statchip { display: inline-flex; gap: 6px; align-items: center; padding: 6px 12px; border-radius: var(--r-md); background: var(--card); border: 1px solid var(--hair); font-weight: 700; font-size: var(--fs-sm); }
.statchip .ic { color: var(--saffron); }
.statchip.xp .ic { color: var(--indigo); }
.goal { display: grid; grid-template-columns: auto 1fr; gap: 18px; align-items: center; }
.ring { inline-size: 104px; block-size: 104px; position: relative; }
.ring svg { inline-size: 100%; block-size: 100%; transform: rotate(-90deg); }
.ring .track { stroke: var(--paper-2); }
.ring .val { stroke: var(--teal-deco); stroke-linecap: round; transition: stroke-dashoffset 900ms var(--ease-out); }
.ring b { position: absolute; inset: 0; display: grid; place-items: center; font: 700 var(--fs-lg) var(--f-display); }
.weekbars { display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px; align-items: end; block-size: 104px; direction: rtl; }
.weekbars .wb { display: grid; gap: 4px; justify-items: center; align-content: end; block-size: 100%; }
.weekbars .wb i { display: block; inline-size: min(24px, 70%); border-radius: 4px 4px 0 0; background: var(--indigo); min-block-size: 2px; }
.weekbars .wb.today i { background: var(--teal-deco); }
.weekbars .wb small { font-size: var(--fs-2xs); color: var(--ink-2); }
.next-list { display: grid; gap: 10px; }
.next-item { display: grid; grid-template-columns: auto 1fr auto; gap: 10px; align-items: center; padding: 10px 12px; border: 1px solid var(--hair);
  border-radius: var(--r-md); text-decoration: none; background: var(--card); }
@media (hover: hover) and (pointer: fine) { .next-item:hover { border-color: var(--indigo); } }
.next-item .t { font-weight: 700; }
.plan-days { display: grid; gap: 8px; }
.plan-day { display: grid; grid-template-columns: 70px 1fr; gap: 10px; padding: 8px 12px; border-radius: var(--r-md); border: 1px solid var(--hair); font-size: var(--fs-sm); }
.plan-day.today { border-color: var(--teal-deco); background: color-mix(in srgb, var(--teal-deco) 7%, var(--card)); }
.plan-day b { font-size: var(--fs-sm); }
.plan-day ul { margin: 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: 6px; }
.plan-day li a { position: relative; display: inline-flex; align-items: center; min-block-size: 32px; padding: 2px 10px; border-radius: 999px; background: var(--paper-2); text-decoration: none; font-size: var(--fs-xs); }
.plan-day li a::before { content: ""; position: absolute; inset: -6px 0; }
.meter { display: grid; gap: 4px; }
.meter .bar { block-size: 8px; }
.meter .row { justify-content: space-between; font-size: var(--fs-sm); }
.countdown { font: 800 var(--fs-2xl) var(--f-display); color: var(--indigo); }

/* catalog --------------------------------------------------------------------- */
.unit { display: grid; gap: 10px; margin-block-end: 24px; }
.unit h2 { font-size: var(--fs-md); display: flex; gap: 8px; align-items: center; }
.lcards { display: grid; gap: 10px; grid-template-columns: 1fr; }
@media (min-width: 700px) { .lcards { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .lcards { grid-template-columns: repeat(3, 1fr); } }
.lcardx { display: grid; gap: 6px; padding: 14px; border-radius: var(--r-lg); border: 1px solid var(--hair); background: var(--card); text-decoration: none;
  transition: transform 180ms var(--ease-out), border-color 180ms; }
@media (hover: hover) and (pointer: fine) { .lcardx:hover { transform: translateY(-2px); border-color: var(--indigo); } }
.lcardx h3 { font-size: var(--fs-base); line-height: 1.6; }
.lcardx p { color: var(--ink-2); font-size: var(--fs-sm); }
.lcardx .mini { block-size: 6px; border-radius: 6px; background: var(--paper-2); overflow: hidden; }
.lcardx .mini i { display: block; block-size: 100%; background: var(--ok); }
.lcardx.done { border-color: color-mix(in srgb, var(--ok) 50%, var(--hair)); }

/* lesson intro: teach cards ------------------------------------------------------ */
.teach { display: grid; gap: 12px; }
.tcard { background: var(--card); border: 1px solid var(--hair); border-radius: var(--r-lg); padding: 16px 18px; display: grid; gap: 8px; }
.tcard.tip { border-inline-start: 3px solid var(--saffron); }
.tcard.rule { border-inline-start: 3px solid var(--indigo); }
.tcard h3 { font-size: var(--fs-md); }
.exlist { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
.exlist li { display: grid; gap: 2px; padding: 8px 12px; background: var(--paper-2); border-radius: var(--r-sm); }
.exlist .en { display: block; font-weight: 600; }
.exlist .fa { color: var(--ink-2); font-size: var(--fs-sm); }
.ttable { inline-size: 100%; border-collapse: collapse; font-size: var(--fs-sm); direction: ltr; }
.ttable th, .ttable td { border: 1px solid var(--hair); padding: 8px 10px; text-align: start; }
.ttable th { background: var(--paper-2); }
.passage { background: var(--card); border: 1px solid var(--hair); border-radius: var(--r-lg); padding: 16px 18px; display: grid; gap: 8px; }
.passage .text { white-space: pre-line; line-height: 1.8; }
.draftflag { font-size: var(--fs-xs); color: var(--ink-2); display: inline-flex; gap: 6px; align-items: center; }

/* lesson player extras ----------------------------------------------------------- */
.qcontext { color: var(--ink-2); font-weight: 500; }
.gapline { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.gapline input { max-inline-size: 360px; direction: ltr; }
.pool, .tline { display: flex; flex-wrap: wrap; gap: 6px; min-block-size: 56px; padding: 8px; border-radius: var(--r-md); direction: ltr; }
.tline { border: 1.5px dashed var(--hair); background: var(--paper-2); }
.matchrow { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; align-items: center; padding: 6px 0; border-block-end: 1px solid var(--hair); }
.matchrow select { min-block-size: 44px; }
.matchrow.ok { color: var(--ok); }
.matchrow.no { color: var(--bad); }
.tokens { display: flex; flex-wrap: wrap; gap: 8px; direction: ltr; }
.token { font: inherit; font-weight: 600; padding: 6px 12px; border-radius: var(--r-sm); border: 1.5px solid var(--hair); background: var(--card); cursor: pointer; min-block-size: 44px; }
@media (hover: hover) and (pointer: fine) { .token:hover:not([disabled]) { border-color: var(--indigo); } }
.token.right { border-color: var(--ok); background: color-mix(in srgb, var(--ok) 14%, var(--card)); }
.token.wrong { border-color: var(--bad); background: color-mix(in srgb, var(--bad) 12%, var(--card)); }
.tfbtns { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.play-btn { display: inline-flex; gap: 6px; align-items: center; justify-content: center; min-block-size: 44px; min-inline-size: 44px; padding-inline: 12px;
  border-radius: 999px; border: 1.5px solid var(--indigo); background: color-mix(in srgb, var(--indigo) 8%, var(--card)); color: var(--indigo); font-weight: 700; font-size: var(--fs-sm); }
.play-btn .ic { inline-size: 18px; block-size: 18px; }
.play-btn.big { min-block-size: 60px; min-inline-size: 60px; }
.play-btn.big .ic { inline-size: 24px; block-size: 24px; }
.play-btn.playing { background: var(--indigo); color: var(--on-indigo); }
.play-btn[disabled] { opacity: 0.5; cursor: not-allowed; }
.rec { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.rec-btn { display: inline-flex; gap: 8px; align-items: center; min-block-size: 44px; padding-inline: 16px; border-radius: 999px; border: 1.5px solid var(--bad);
  color: var(--bad); background: var(--card); font-weight: 700; }
.rec-btn.on { background: var(--bad); color: #fff; }
.rec-time { font: 700 1rem var(--f-display); direction: ltr; }
.rec audio { max-inline-size: 100%; }

/* tests list & player ----------------------------------------------------------- */
.tcardx { display: grid; gap: 10px; }
.tcardx .meta { display: flex; flex-wrap: wrap; gap: 8px; color: var(--ink-2); font-size: var(--fs-sm); }
.tp { --tp-bar: 56px; min-block-size: 100dvh; display: grid; grid-template-rows: auto 1fr auto; background: var(--paper); }
.tp-top { position: sticky; inset-block-start: 0; z-index: 20; display: flex; gap: 12px; align-items: center; padding: 8px 16px; background: var(--card);
  border-block-end: 1px solid var(--hair); }
.tp-title { font-weight: 700; font-size: var(--fs-sm); margin-inline-end: auto; }
.tp-timer { display: inline-flex; gap: 6px; align-items: center; font: 700 1.05rem var(--f-display); direction: ltr; padding: 4px 10px; border-radius: var(--r-sm); background: var(--paper-2); }
.tp-timer.low { background: color-mix(in srgb, var(--bad) 18%, var(--card)); color: var(--bad); }
.tp-body { display: grid; gap: 0; grid-template-columns: 1fr; direction: ltr; text-align: left; font-family: "Inter Var", system-ui, sans-serif; }
.tp-body[data-size="l"] { font-size: 1.12rem; }
.tp-body[data-size="xl"] { font-size: 1.25rem; }
/* Desktop split: the player is exactly one screen (top bar, body, navigator) and each pane scrolls on its own. The panes
   sit inside .tp-section (display: contents), so they are targeted directly; a "> *" rule would hit the section. */
@media (min-width: 980px) {
  .tp:has(.tp-body.split) { block-size: 100dvh; min-block-size: 0; }
  .tp-body.split { grid-template-columns: 1fr 1fr; grid-template-rows: minmax(0, 1fr); min-block-size: 0; }
  .tp-body.split .tp-pane { overflow: auto; overscroll-behavior: contain; min-block-size: 0; }
}
.tp-pane { padding: 20px 24px 40px; }
.tp-passage { background: var(--card); border-inline-end: 1px solid var(--hair); }
.tp-passage h2 { font-size: 1.3rem; margin-block-end: 12px; font-family: inherit; }
.tp-passage p { margin-block-end: 14px; line-height: 1.75; }
.tp-passage .plabel { font-weight: 800; margin-inline-end: 6px; }
.tp-passage mark.hl { background: color-mix(in srgb, var(--saffron) 55%, transparent); color: inherit; border-radius: 3px; }
.tp-section { display: none; }
.tp-section.on { display: contents; }
.qgroup { display: grid; gap: 14px; margin-block-end: 26px; }
.qgroup .instr { font-weight: 700; background: var(--paper-2); padding: 10px 14px; border-radius: 12px; white-space: pre-line; }
.qgroup .instr small { display: block; font-weight: 500; color: var(--ink-2); }
.qitem { display: grid; gap: 8px; padding: 12px 14px; border: 1px solid var(--hair); border-radius: 14px; background: var(--card); scroll-margin-block-start: 80px; }
.qitem.flagged { border-color: var(--saffron); box-shadow: inset 4px 0 0 var(--saffron); }
.qhead { display: flex; gap: 10px; align-items: baseline; }
.qnum { font-weight: 800; min-inline-size: 30px; display: inline-grid; place-items: center; block-size: 30px; border-radius: 8px; background: var(--ink); color: var(--paper); font-size: 0.85rem; }
.flagbtn { margin-inline-start: auto; background: none; border: 0; color: var(--ink-2); min-block-size: 36px; min-inline-size: 36px; cursor: pointer; border-radius: 8px; }
.flagbtn[aria-pressed="true"] { color: var(--saffron); }
.qopts { display: grid; gap: 6px; }
.qopt { display: flex; gap: 10px; align-items: flex-start; padding: 8px 10px; border-radius: 10px; cursor: pointer; min-block-size: 44px; }
@media (hover: hover) and (pointer: fine) { .qopt:hover { background: var(--paper-2); } }
.qopt input { margin-block-start: 5px; inline-size: 18px; block-size: 18px; flex: none; }
.qopt:has(input:checked) { background: color-mix(in srgb, var(--indigo) 10%, var(--card)); }
.gapin { display: inline-block; inline-size: 11em; min-block-size: 36px !important; padding: 4px 8px !important; border-radius: 8px !important; margin: 2px 4px; }
.inlinegap { white-space: pre-line; line-height: 2.4; background: var(--card); border: 1px solid var(--hair); border-radius: 14px; padding: 14px 16px; }
.inlinegap .qnum { margin-inline-end: 2px; block-size: 24px; min-inline-size: 24px; font-size: 0.75rem; }
.optlist { display: grid; gap: 4px; padding: 10px 14px; border: 1px dashed var(--hair); border-radius: 12px; font-size: 0.95rem; }
.tp-audio { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; padding: 14px 16px; border-radius: 16px; background: var(--card); border: 1px solid var(--hair); margin-block-end: 18px; }
.tp-audio .ctx { flex: 1 1 260px; color: var(--ink-2); }
.tp-audio progress { inline-size: 100%; block-size: 8px; }
.tp-nav { position: sticky; inset-block-end: 0; z-index: 20; display: flex; gap: 6px; align-items: center; padding: 8px 12px; background: var(--card);
  border-block-start: 1px solid var(--hair); overflow-x: auto; direction: ltr; }
.tp-nav .sec { font-weight: 800; font-size: 0.8rem; padding-inline: 8px; white-space: nowrap; color: var(--ink-2); }
.navq { flex: none; inline-size: 34px; block-size: 34px; border-radius: 8px; border: 1px solid var(--hair); background: var(--paper); font: 700 0.82rem var(--f-display); cursor: pointer; position: relative; }
.navq.answered { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.navq.flagged::after { content: ""; position: absolute; inset-block-start: -3px; inset-inline-end: -3px; inline-size: 9px; block-size: 9px; border-radius: 50%; background: var(--saffron); border: 2px solid var(--card); }
.navq.current { outline: 3px solid var(--indigo); outline-offset: 1px; }
.tp-dialog { border: 0; border-radius: 22px; padding: 22px; inline-size: min(92vw, 520px); background: var(--card); color: var(--ink); box-shadow: var(--shadow); }
.tp-dialog::backdrop { background: rgb(15 14 34 / 0.5); }
.tp-dialog .grid-q { display: grid; grid-template-columns: repeat(auto-fill, minmax(40px, 1fr)); gap: 6px; direction: ltr; margin-block: 12px; }

/* result ---------------------------------------------------------------------------- */
.score-hero { display: grid; gap: 14px; grid-template-columns: 1fr; align-items: center; }
@media (min-width: 760px) { .score-hero { grid-template-columns: auto 1fr; } }
.score-num { font: 800 var(--fs-3xl)/1 var(--f-display); color: var(--indigo); direction: ltr; }
.score-sub { color: var(--ink-2); }
.review-list { display: grid; gap: 10px; }
.rv-item { display: grid; gap: 6px; padding: 10px 14px; border-radius: var(--r-md); border: 1px solid var(--hair); background: var(--card); }
.rv-item.ok { border-inline-start: 3px solid var(--ok); }
.rv-item.no { border-inline-start: 3px solid var(--bad); }
.rv-item .ans { direction: ltr; text-align: left; display: flex; flex-wrap: wrap; gap: 12px; font-size: var(--fs-sm); }
.rv-item .evidence { direction: ltr; text-align: left; font-style: italic; color: var(--ink-2); border-inline-start: 3px solid var(--hair); padding-inline-start: 10px; }
.transcript { direction: ltr; text-align: left; display: grid; gap: 6px; font-size: var(--fs-sm); }
.transcript b { color: var(--indigo); }

/* chat (tutor) ------------------------------------------------------------------------ */
.chat { display: grid; grid-template-rows: auto 1fr auto; gap: 12px; min-block-size: calc(100dvh - 200px); }
.bubbles { display: grid; gap: 10px; align-content: start; padding-block: 8px; }
.bubble { max-inline-size: 85%; padding: 8px 12px; border-radius: var(--r-lg); line-height: 1.6; direction: ltr; text-align: left; }
.bubble.partner { background: var(--card); border: 1px solid var(--hair); justify-self: end; border-end-end-radius: 6px; }
.bubble.learner { background: var(--indigo); color: var(--on-indigo); justify-self: start; border-end-start-radius: 6px; }
.coach { justify-self: start; max-inline-size: 85%; font-size: var(--fs-sm); background: color-mix(in srgb, var(--saffron) 20%, var(--card)); border-radius: var(--r-md); padding: 8px 12px; }
.coach .fix { direction: ltr; text-align: left; }
.composer { display: flex; gap: 8px; position: sticky; inset-block-end: 76px; background: var(--paper); padding-block: 8px; }
@media (min-width: 900px) { .composer { inset-block-end: 0; } }
.composer input { direction: ltr; }
.goals { display: flex; flex-wrap: wrap; gap: 6px; }

/* pricing ------------------------------------------------------------------------------ */
.plans3 { display: grid; gap: 12px; grid-template-columns: 1fr; }
@media (min-width: 900px) { .plans3 { grid-template-columns: repeat(3, 1fr); } }
.plan .amount { font: 800 var(--fs-2xl) var(--f-display); }
.plan .was { text-decoration: line-through; color: var(--ink-2); font-size: var(--fs-sm); }
.plan .badge-top { position: absolute; inset-block-start: -11px; inset-inline-start: 18px; background: var(--indigo); color: var(--on-indigo); font-size: var(--fs-xs); font-weight: 700; padding: 1px 12px; border-radius: 999px; }
.plan { position: relative; }
.compare { inline-size: 100%; border-collapse: collapse; }
.compare th, .compare td { padding: 8px 10px; border-block-end: 1px solid var(--hair); text-align: start; font-size: var(--fs-sm); }

/* tables --------------------------------------------------------------------------------- */
.table-wrap { overflow-x: auto; border: 1px solid var(--hair); border-radius: var(--r-md); background: var(--card); }
.table { inline-size: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.table th, .table td { padding: 8px 12px; text-align: start; border-block-end: 1px solid var(--hair); vertical-align: middle; }
.table th { font-size: var(--fs-xs); color: var(--ink-2); font-weight: 600; background: var(--paper-2); position: sticky; inset-block-start: 0; }
.table tr:last-child td { border-block-end: 0; }
.table td.num, .table th.num { text-align: end; font-variant-numeric: tabular-nums; }
.pager { display: flex; gap: 12px; align-items: center; justify-content: center; margin-block: 18px; }

/* prose (legal pages, panel previews; articles use .bl-prose in blog.css) ------------------- */
.prose { max-inline-size: 70ch; line-height: 1.95; font-size: var(--fs-md); }
.prose h2 { font-size: var(--fs-lg); margin-block: 28px 8px; }
.prose h3 { font-size: var(--fs-md); margin-block: 20px 6px; }
.prose p { margin-block: 0 14px; }
.prose ul, .prose ol { padding-inline-start: 22px; margin-block: 0 14px; }
.prose li { margin-block: 4px; }
.prose a { color: var(--indigo); }
.prose code { background: var(--paper-2); padding: 1px 6px; border-radius: 6px; }

/* speaking / recorder ----------------------------------------------------------------- */
.prompt-big { font-size: 1.0625rem; font-weight: 600; direction: ltr; text-align: left; line-height: 1.7; }
.bullets { direction: ltr; text-align: left; margin: 0; padding-inline-start: 20px; }
.phase { display: inline-flex; gap: 6px; align-items: center; font-weight: 700; font-size: var(--fs-sm); padding: 4px 12px; border-radius: 999px; background: var(--paper-2); }
.phase.prep { background: color-mix(in srgb, var(--saffron) 25%, var(--card)); }
.phase.speak { background: color-mix(in srgb, var(--bad) 15%, var(--card)); color: var(--bad); }
.wordmarks { direction: ltr; text-align: left; display: flex; flex-wrap: wrap; gap: 4px 6px; }
.wordmarks span { padding: 2px 6px; border-radius: 6px; }
.wordmarks .ok { background: color-mix(in srgb, var(--ok) 15%, var(--card)); }
.wordmarks .no { background: color-mix(in srgb, var(--bad) 15%, var(--card)); text-decoration: underline wavy var(--bad); }

/* pronunciation game ---------------------------------------------------------------- */
.pairgame { display: grid; gap: 16px; justify-items: center; text-align: center; }
.pairbtns { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; inline-size: min(100%, 460px); }
.pairbtn { min-block-size: 72px; border-radius: var(--r-lg); border: 1.5px solid var(--hair); background: var(--card); font: 700 var(--fs-xl) var(--f-display); direction: ltr; display: grid; gap: 2px; place-items: center; }
.pairbtn small { font: 500 var(--fs-xs) var(--f-body); color: var(--ink-2); }
.pairbtn.right { border-color: var(--ok); background: color-mix(in srgb, var(--ok) 14%, var(--card)); }
.pairbtn.wrong { border-color: var(--bad); background: color-mix(in srgb, var(--bad) 12%, var(--card)); }

/* techniques ------------------------------------------------------------------------- */
.shadow-line { direction: ltr; text-align: left; font-size: 1.0625rem; line-height: 1.8; padding: 12px 14px; border-radius: var(--r-md); background: var(--card); border: 1px solid var(--hair); transition: opacity 400ms, filter 400ms; }
.shadow-line.fade { opacity: 0.35; }
.shadow-line.hidden-text { filter: blur(7px); user-select: none; }
.shadow-line .w.cur { background: color-mix(in srgb, var(--saffron) 50%, transparent); border-radius: 4px; }
.seg { display: inline-flex; border: 1px solid var(--hair); border-radius: 999px; overflow: hidden; }
.seg button { border: 0; background: var(--card); padding: 6px 12px; min-block-size: var(--ctl-sm); font-weight: 600; font-size: var(--fs-sm); }
.seg button[aria-pressed="true"] { background: var(--ink); color: var(--paper); }
.diff { direction: ltr; text-align: left; line-height: 2; }
.diff ins { background: color-mix(in srgb, var(--ok) 20%, var(--card)); text-decoration: none; border-radius: 4px; padding: 0 3px; }
.diff del { background: color-mix(in srgb, var(--bad) 18%, var(--card)); border-radius: 4px; padding: 0 3px; }
.bigtimer { font: 700 var(--fs-3xl)/1 var(--f-display); direction: ltr; }

/* empty / misc -------------------------------------------------------------------------- */
.empty { text-align: center; padding: 32px 16px; color: var(--ink-2); display: grid; gap: 10px; justify-items: center; font-size: var(--fs-sm); }
.empty .ic { inline-size: 32px; block-size: 32px; }
.more-words { margin-block: 12px; }
.mw-list { margin: 0; padding-inline-start: 18px; display: grid; gap: 6px; }
.guest-cta { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 16px; margin-block: 12px; padding: 12px 16px; border-radius: var(--r-lg); background: color-mix(in srgb, var(--teal) 10%, var(--card)); }
.guest-cta p { margin: 0; flex: 1 1 260px; font-size: var(--fs-sm); line-height: 1.7; }
.lockbox { display: grid; gap: 10px; justify-items: start; padding: 16px; border-radius: var(--r-lg); border: 1.5px dashed var(--saffron); background: color-mix(in srgb, var(--saffron) 8%, var(--card)); }
.kbd-hint { font-size: var(--fs-xs); color: var(--ink-2); }
details.more summary { cursor: pointer; font-weight: 700; min-block-size: 44px; display: flex; align-items: center; }
.tools-grid .card .ic { inline-size: 22px; block-size: 22px; color: var(--indigo); }
@media (hover: hover) and (pointer: fine) { html[data-motion="0"] .card.link:hover, html[data-motion="0"] .lcardx:hover { transform: none; } }

/* data-viz series tokens (dataviz reference palette, validated light + dark; light slots 3–5 < 3:1 → charts
   always ship a legend and a table view) ------------------------------------------------------------------ */
:root { --s1: #2a78d6; --s2: #eb6834; --s3: #1baf7a; --s4: #eda100; --s5: #e87ba4; --s6: #008300; --grid: #e4dfd3; --axis: #4a4766; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --s1: #3987e5; --s2: #d95926; --s3: #199e70; --s4: #c98500; --s5: #d55181; --s6: #008300; --grid: #2b2958; --axis: #b6b2d1; } }
:root[data-theme="dark"] { --s1: #3987e5; --s2: #d95926; --s3: #199e70; --s4: #c98500; --s5: #d55181; --s6: #008300; --grid: #2b2958; --axis: #b6b2d1; }
/* content pictures (templates/_figure.html): our own SVGs on a light "paper" card in both themes */
.cfig { margin: 0; display: grid; gap: 6px; direction: ltr; background: #fffdf8; border: 1px solid var(--hair); border-radius: var(--r-lg); padding: 10px; }
.cfig img { display: block; inline-size: 100%; max-block-size: 70vh; block-size: auto; object-fit: contain; }
.cfig figcaption { display: flex; justify-content: space-between; gap: 8px; font-size: var(--fs-sm, .875rem); color: #4a4766; text-align: left; }
.cfig-zoom { margin-inline-start: auto; color: #2a5bb8; white-space: nowrap; }
.chart-maps { display: grid; gap: 12px; }
.chart-maps h4 { font-size: var(--fs-base); text-align: left; margin: 0; }
figure.chart { margin: 0; } /* no UA figure indent: the visual uses the full width of its column */
.chart { background: var(--card); border: 1px solid var(--hair); border-radius: var(--r-lg); padding: 14px; display: grid; gap: 10px; direction: ltr; }
.chart h3 { font-size: var(--fs-base); text-align: left; font-family: "Inter Var", system-ui, sans-serif; }
.chart svg { inline-size: 100%; block-size: auto; overflow: visible; }
.chart .gridline { stroke: var(--grid); stroke-width: 1; }
.chart .tick { fill: var(--axis); font: 500 11px "Inter Var", system-ui, sans-serif; }
.chart .vlabel { fill: var(--ink); font: 700 11px "Inter Var", system-ui, sans-serif; }
.chart .legend { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: var(--fs-xs); color: var(--ink); }
.chart .legend span { display: inline-flex; gap: 6px; align-items: center; }
.chart .legend i { inline-size: 12px; block-size: 12px; border-radius: 3px; display: inline-block; }
@media (hover: hover) and (pointer: fine) { .chart .hit:hover + .mark, .chart .mark:hover { opacity: 0.8; } }
.qtext { white-space: pre-line; }

/* test player: split handle, mobile tabs, contrast themes, hidden timer (docs/REVERSE-ENGINEERING.md §3.4) */
.tp-tabs { display: none; margin: 8px 12px 0; }
.tp-handle { display: none; }
@media (min-width: 980px) {
  .tp-body.split { grid-template-columns: var(--split, 50%) 8px 1fr; }
  .tp-handle { display: block; cursor: col-resize; background: var(--hair); position: relative; }
  .tp-handle::after { content: "⟷"; position: absolute; inset-block-start: 50%; inset-inline-start: 50%; transform: translate(-50%, -50%);
    background: var(--card); border: 1px solid var(--hair); border-radius: 8px; font-size: 12px; padding: 4px 2px; }
  .tp-handle:focus-visible { outline: 3px solid var(--indigo); }
}
@media (max-width: 979px) {
  .tp-tabs { display: inline-flex; }
  .tp-body.split[data-view="passage"] .tp-questions, .tp-body.split[data-view="questions"] .tp-passage { display: none; }
}
.tp[data-contrast="bw"], .tp[data-contrast="bw"] .tp-pane, .tp[data-contrast="bw"] .qitem, .tp[data-contrast="bw"] .tp-top, .tp[data-contrast="bw"] .tp-nav,
.tp[data-contrast="bw"] .inlinegap, .tp[data-contrast="bw"] .qgroup .instr, .tp[data-contrast="bw"] input, .tp[data-contrast="bw"] select { background: #000 !important; color: #fff !important; }
.tp[data-contrast="yb"], .tp[data-contrast="yb"] .tp-pane, .tp[data-contrast="yb"] .qitem, .tp[data-contrast="yb"] .tp-top, .tp[data-contrast="yb"] .tp-nav,
.tp[data-contrast="yb"] .inlinegap, .tp[data-contrast="yb"] .qgroup .instr, .tp[data-contrast="yb"] input, .tp[data-contrast="yb"] select { background: #000 !important; color: #ffeb3b !important; }
.tp[data-contrast] .navq { color: inherit; background: transparent; border-color: currentColor; }
.tp-timer.hidden-timer #tp-time { visibility: hidden; }
.rv-item mark.ev, .tp-passage mark.ev { background: color-mix(in srgb, var(--teal-deco) 30%, transparent); border-radius: 3px; }
.rv-item .btn { justify-self: start; }
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }
input[type="radio"], input[type="checkbox"], input[type="range"], progress { accent-color: var(--indigo); }
.tp-dialog .stack > div { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; }
.tcard h2, .passage h2 { font-size: var(--fs-md); }

/* ==== UI refresh (docs/UI-AUDIT.md): shared components ========================================================= */
/* --well: an inset surface that stays visible on cards in dark mode too (there --paper-2 equals --card) */
:root { --well: var(--paper-2); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --well: #262356; } }
:root[data-theme="dark"] { --well: #262356; }
/* grid/flex children never force a horizontal scroll (long <select> options, long words) */
.dash > *, .grid > *, .stack > *, .form-grid > * { min-inline-size: 0; }
select, input, textarea { max-inline-size: 100%; min-inline-size: 0; }
.field > select, .field > textarea { inline-size: 100%; }

/* cards: a resting card has a hairline and a 1px lift; link cards rise on hover */
.card { box-shadow: var(--e1); }
.card > h2:has(> .ic:first-child), .card > .row > h2:has(> .ic:first-child) { display: flex; gap: 10px; align-items: center; }
.card > h2 > .ic:first-child, .card > .row > h2 > .ic:first-child { inline-size: 30px; block-size: 30px; padding: 6px; border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--indigo) 11%, var(--card)); color: var(--indigo); }
@media (hover: hover) and (pointer: fine) { .card.link:hover, .lcardx:hover { box-shadow: var(--e2); } }
.section-head-row { display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: baseline; justify-content: space-between; margin-block-end: 12px; }

/* forms: 3:1 control borders (WCAG 1.4.11), one select style with a drawn chevron on the end side, hover + disabled */
input[type="text"], input[type="tel"], input[type="email"], input[type="number"], input[type="search"], input[type="date"],
input[type="datetime-local"], input[type="password"], .input, select, textarea { border-width: 1px; border-color: color-mix(in srgb, var(--line) 80%, var(--hair)); }
@media (hover: hover) and (pointer: fine) { input[type="text"]:hover, input[type="tel"]:hover, input[type="email"]:hover, input[type="number"]:hover, input[type="search"]:hover, input[type="password"]:hover, .input:hover, select:hover, textarea:hover { border-color: var(--line); } }
input::placeholder, textarea::placeholder { color: color-mix(in srgb, var(--ink-2) 75%, transparent); opacity: 1; }
select:focus-visible, textarea:focus-visible { outline: 2px solid transparent; box-shadow: 0 0 0 3px color-mix(in srgb, var(--indigo) 32%, transparent); border-color: var(--indigo); }
input:disabled, select:disabled, textarea:disabled { opacity: 0.6; cursor: not-allowed; }
select:not([multiple]):not(.tp select) { appearance: none; -webkit-appearance: none; min-block-size: var(--ctl); padding-inline: 12px 34px; line-height: 1.5; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m6 9 6 6 6-6' fill='none' stroke='%238a859c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-size: 16px; background-position: left 12px center; }
[dir="ltr"] select:not([multiple]):not(.tp select), select[dir="ltr"]:not([multiple]):not(.tp select) { padding-inline: 12px 34px; background-position: right 12px center; }
.matchrow select:not([multiple]) { min-block-size: 44px; }
.field > label + .help, .field > .label + .help { margin-block-start: -2px; }
.errorlist { display: grid; gap: 2px; }
.errorlist li::before { content: "⚠ "; }
/* radio/checkbox chips: the native dot sits inside a pill; checked = indigo ring + tint */
.choices label { transition: border-color 120ms var(--ease-std), background-color 120ms var(--ease-std); border-width: 1px; border-color: color-mix(in srgb, var(--line) 60%, var(--hair)); }
@media (hover: hover) and (pointer: fine) { .choices label:hover { border-color: var(--indigo); } }
.choices label:has(input:focus-visible) { outline: 2px solid var(--indigo); outline-offset: 2px; }
.choices input[type="radio"], .choices input[type="checkbox"], .checkbox input { inline-size: 16px; block-size: 16px; margin: 0; flex: none; }
.checkbox { min-block-size: 44px; align-items: center; cursor: pointer; }
.checkbox input { margin-block-start: 0; }

/* disclosure: every "more" <details> gets a chevron that turns, not the browser triangle */
details.more > summary, .passage details > summary, .prompt-card details > summary, .stack > details:not([class]) > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 10px; min-block-size: 44px; font-weight: 600; }
details.more > summary::-webkit-details-marker, .passage details > summary::-webkit-details-marker, .prompt-card details > summary::-webkit-details-marker,
.stack > details:not([class]) > summary::-webkit-details-marker { display: none; }
details.more > summary::after, .passage details > summary::after, .prompt-card details > summary::after, .stack > details:not([class]) > summary::after {
  content: ""; inline-size: 7px; block-size: 7px; margin-inline-start: auto; flex: none; border: solid currentColor; border-width: 0 1.5px 1.5px 0;
  transform: translateY(-2px) rotate(45deg); opacity: 0.6; transition: transform 160ms var(--ease-std); }
details[open].more > summary::after, .passage details[open] > summary::after, .prompt-card details[open] > summary::after, .stack > details[open]:not([class]) > summary::after {
  transform: translateY(2px) rotate(-135deg); }
@media (hover: hover) and (pointer: fine) { details.more > summary:hover, .passage details > summary:hover { color: var(--indigo); } }
details.card.more { padding-block: 6px; }
details.card.more[open] { padding-block-end: 16px; }
details.card.more > summary { min-block-size: 44px; }

/* toasts: tinted, with a state dot; they stay in flow under the header */
.toast { display: flex; gap: 10px; align-items: center; font-weight: 500; box-shadow: var(--e1); transition: opacity 400ms var(--ease-std); }
.toast::before { content: ""; inline-size: 8px; block-size: 8px; border-radius: 50%; flex: none; background: var(--indigo); }
.toast.success { background: color-mix(in srgb, var(--ok) 9%, var(--card)); } .toast.success::before { background: var(--ok); }
.toast.error { background: color-mix(in srgb, var(--bad) 8%, var(--card)); } .toast.error::before { background: var(--bad); }
.toast.warning { background: color-mix(in srgb, var(--saffron) 14%, var(--card)); } .toast.warning::before { background: var(--tile-sun-ledge, #c98500); }

/* empty states: icon in a soft tile, title, one line, one action */
.empty { padding: 28px 18px; border-radius: var(--radius); border: 1px dashed var(--line); background: color-mix(in srgb, var(--paper-2) 45%, transparent); }
.empty > .ic:first-child { inline-size: 44px; block-size: 44px; padding: 11px; border-radius: var(--r-md); background: var(--card); color: var(--indigo);
  box-shadow: 0 1px 2px rgb(20 18 43 / 0.06), 0 0 0 1px var(--hair); }
.empty h2, .empty h3 { font-size: var(--fs-md); color: var(--ink); }
.empty p { max-inline-size: 42ch; }
.card .empty, .empty.flat { border: 0; background: none; padding: 20px 8px; }
.empty-mini { display: flex; gap: 10px; align-items: center; padding: 10px 12px; border-radius: var(--r-md); background: var(--well); color: var(--ink-2); font-size: var(--fs-sm); }
.empty-mini .ic { color: var(--indigo); flex: none; }

/* tables: row headers, zebra-free hover, readable on phones */
.table th[scope="row"] { font-size: var(--fs-sm); color: var(--ink); background: none; position: static; font-weight: 700; }
@media (hover: hover) and (pointer: fine) { .table tbody tr:hover td, .table tbody tr:hover th { background: color-mix(in srgb, var(--paper-2) 55%, transparent); } }
.table .ic { inline-size: 16px; block-size: 16px; color: var(--ok); }
.table td .ic { display: inline-block; vertical-align: -4px; }

/* lists: Persian ordinal markers in Persian lists; zero specificity, so any component's `list-style: none` (answer grid,
   steps, chips) still wins */
:where(ol:lang(fa)) { list-style-type: persian; }
ol.steps, ol.trail-nodes, ol.week-dots, ol.sec-steps { list-style: none; }

/* disabled buttons never look clickable */
.btn[disabled], .btn[aria-disabled="true"] { box-shadow: none; transform: none; }
.btn[aria-busy="true"] { opacity: .72; cursor: progress; } /* a POST form on its way (ui.js resend guard) */
.btn-primary:focus-visible, .btn-sun:focus-visible { outline-offset: 2px; }

/* page header: kicker + title + lead keep one rhythm everywhere */
.page-head .kicker { margin-block-end: -2px; }
.page-head p:not(.kicker) { text-wrap: pretty; }

/* state pages: 404, offline, maintenance, 500 */
.state-page { min-block-size: calc(100dvh - 260px); display: grid; place-items: center; padding-block: 40px; }
.state-card { display: grid; gap: 12px; justify-items: center; text-align: center; max-inline-size: 440px; }
.state-card .khatam { inline-size: 96px; }
.state-card h1 { font-size: var(--fs-h1); }
.state-card p { color: var(--ink-2); }
.state-card .row { justify-content: center; margin-block-start: 6px; }
.state-code { font: 700 var(--fs-2xs)/1 var(--f-display); letter-spacing: var(--ls-caps); color: var(--ink-2); direction: ltr; }

/* pricing (billing/pricing.html): price line, feature ticks, one buy button, coupon behind a disclosure */
.plans3 { align-items: stretch; }
.plans3 .plan { box-shadow: var(--e1); display: flex; flex-direction: column; }
.plans3 .plan.featured { box-shadow: 0 14px 32px -22px color-mix(in srgb, var(--indigo) 70%, transparent); background: linear-gradient(170deg, color-mix(in srgb, var(--indigo) 6%, var(--card)), var(--card) 55%); }
.plans3 .plan h3 { font-size: var(--fs-lg); }
.price-line { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; }
.price-line .cur { color: var(--ink-2); font-weight: 600; font-size: var(--fs-sm); }
.price-line .was { color: var(--ink-2); font-size: var(--fs-sm); }
.plans3 .plan ul.feat { gap: 6px; }
.plans3 .plan ul.feat li::before { content: none; }
.plans3 .plan ul.feat li { align-items: flex-start; }
.plans3 .plan ul.feat .ic { inline-size: 18px; block-size: 18px; padding: 3px; border-radius: 50%; margin-block-start: 3px; stroke-width: 2.5; background: color-mix(in srgb, var(--ok) 14%, var(--card)); color: var(--ok); }
.plan-buy { margin-block-start: auto; gap: 10px; }
.plan-buy .btn { inline-size: 100%; }
details.coupon > summary { list-style: none; cursor: pointer; min-block-size: 44px; display: inline-flex; align-items: center; color: var(--indigo); font-weight: 600; font-size: var(--fs-sm); }
details.coupon > summary::-webkit-details-marker { display: none; }
details.coupon[open] > summary { color: var(--ink-2); }
details.coupon input { margin-block-start: 4px; }
.compare-t { table-layout: fixed; }
.compare-t th[scope="col"] { text-align: center; }
.compare-t th[scope="col"]:first-child { inline-size: 40%; }
.compare-t td { text-align: center; font-size: var(--fs-sm); }
.compare-t .hl { background: color-mix(in srgb, var(--indigo) 5%, transparent); }
.compare-t thead .hl { color: var(--indigo); }
@media (max-width: 559px) { .compare-t th[scope="row"] { font-size: 0.85rem; } .compare-t td { font-size: 0.82rem; padding-inline: 6px; } .compare-t th, .compare-t td { padding-inline: 8px; } }

/* profile: danger zone + referral code */
.btn-danger { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 55%, var(--hair)); background: var(--card); }
@media (hover: hover) and (pointer: fine) { .btn-danger:hover { background: color-mix(in srgb, var(--bad) 9%, var(--card)); border-color: var(--bad); } }
.card.danger-zone { border-color: color-mix(in srgb, var(--bad) 30%, var(--hair)); }
.card.danger-zone h2 { color: var(--bad); }
.ref-code { justify-self: start; }
.ref-code .en { font: 700 var(--fs-lg)/1 var(--f-display); letter-spacing: 0.12em; padding: 8px 14px; border-radius: var(--r-md); border: 1.5px dashed var(--line); background: var(--well); }
form.card > .btn-primary[type="submit"] { justify-self: start; min-inline-size: 160px; }

/* notice row: icon + two lines + one action (due reviews, resumable work) */
.notice { display: flex; flex-wrap: wrap; gap: 10px 12px; align-items: center; padding: 12px 14px; margin-block-end: 16px; border-radius: var(--r-lg);
  background: var(--card); border: 1px solid var(--hair); box-shadow: var(--e1); }
.notice.hot { background: color-mix(in srgb, var(--saffron) 12%, var(--card)); border-color: color-mix(in srgb, var(--saffron) 55%, var(--hair)); }
.notice .nt-ic { inline-size: 36px; block-size: 36px; flex: none; border-radius: var(--r-md); display: grid; place-items: center; background: var(--tile-sun, #ffb627); color: var(--on-sun, #14122b); }
.notice .nt-text { display: grid; gap: 2px; flex: 1 1 200px; min-inline-size: 0; }
.notice .nt-text small { color: var(--ink-2); font-size: var(--fs-xs); }
/* technique cards: action pinned to the bottom so a row of cards lines up */
.tech-card { align-content: stretch; grid-template-rows: auto auto 1fr auto; }
.tech-card > .btn { justify-self: start; }
.tech-card .why-line { align-self: start; padding-block-start: 10px; border-block-start: 1px dashed var(--hair); }
@media (max-width: 559px) { .lcardx { padding: 12px 14px; gap: 4px; } }

/* auth: a glazed band on top of the card (brand moment without an image) */
.auth-card { position: relative; overflow: hidden; padding-block-start: 32px; }
.auth-card::before { content: ""; position: absolute; inset-block-start: 0; inset-inline: 0; block-size: 6px;
  background: var(--lattice-light, none), linear-gradient(90deg, var(--sk-listening, #07756d), var(--indigo) 55%, var(--sk-speaking, #b8336a)); }
.auth-card .btn-primary { min-block-size: var(--ctl-lg); font-size: var(--fs-base); }
.auth-card input[dir="ltr"], .auth-card .otp-input { text-align: center; }
.auth-wrap { background: radial-gradient(60% 50% at 50% 30%, color-mix(in srgb, var(--indigo) 7%, transparent), transparent 70%); }
p.en { max-inline-size: 100%; overflow-wrap: anywhere; }
details.card.more li a { display: inline-flex; align-items: center; min-block-size: 44px; }

/* filter pills: one swipeable row per group on phones instead of 7 wrapped rows */
.pill { transition: border-color 120ms, background-color 120ms; white-space: nowrap; }
.pill.on { box-shadow: 0 2px 6px -2px rgb(20 18 43 / 0.35); }
@media (max-width: 759px) {
  .filters { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin-block-end: 10px; padding-block: 2px; padding-inline-end: 24px;
    mask-image: linear-gradient(to left, #000 calc(100% - 28px), transparent); scroll-snap-type: x proximity; }
  .filters::-webkit-scrollbar { display: none; }
  .filters > * { flex: none; scroll-snap-align: start; }
  .filters + :not(.filters) { margin-block-start: 14px; }
}
/* plain links that a flex row blockifies (e.g. recent chats) keep a 40px target */
.row > a:not([class]) { display: inline-flex; align-items: center; min-block-size: 40px; }


/* support launcher (templates/support/_launcher.html; the sheet itself is static/css/support.css, loaded on demand).
   Bottom corner on the inline-start side (right in RTL): the blog's back-to-top and the path's "current" pill sit on the
   inline-end side. Above the tab bar on phones, clear of the Android app's gesture bar (--safe-b). */
.sp-fab { position: fixed; z-index: 54; inset-inline-start: max(16px, var(--safe-r)); inset-block-end: calc(16px + var(--safe-b));
  display: inline-grid; grid-auto-flow: column; gap: 8px; place-items: center; min-inline-size: 52px; block-size: 52px; padding-inline: 14px;
  border-radius: 999px; text-decoration: none; color: var(--on-indigo); background: var(--indigo); box-shadow: var(--e2);
  -webkit-tap-highlight-color: transparent; transition: transform var(--dur-1) var(--ease-std); }
.sp-fab .ic { inline-size: 24px; block-size: 24px; }
.sp-fab-l { display: none; font-size: var(--fs-sm); font-weight: 650; }
.sp-fab:active { transform: scale(0.94); }
.sp-fab:focus-visible { outline: 3px solid var(--indigo); outline-offset: 3px; }
.sp-fab .sp-dot { position: absolute; inset-block-start: 4px; inset-inline-end: 4px; inline-size: 12px; block-size: 12px; border-radius: 50%;
  background: var(--bad); box-shadow: 0 0 0 2px var(--paper); }
body:has(> .tabbar) .sp-fab { inset-block-end: calc(var(--tabbar-h) + var(--safe-b) + 12px); }
/* the tab bar hides while typing (kashi.css); so does the launcher, so it never covers a focused field's neighbours */
body:has(main :is(input:not([type="radio"], [type="checkbox"], [type="range"], [type="button"], [type="submit"], [type="file"], [type="hidden"]), textarea, [contenteditable="true"]):focus) .sp-fab { display: none; }
/* phones: the launcher steps aside while the learner reads down (fx.js sets html.scroll-down) and comes back on any scroll
   up; the page ends with room for it, so the last line or card is never under it */
@media (max-width: 899px) {
  .sp-fab { transition: transform var(--dur-2) var(--ease-std), opacity var(--dur-2) var(--ease-std); }
  html.scroll-down .sp-fab { transform: translateY(calc(100% + 24px)); opacity: 0; pointer-events: none; }
  body:has(.sp-fab):not(:has(.site-footer)) main::after { content: ""; display: block; block-size: 68px; }
  body:has(.sp-fab) .site-footer { padding-block-end: calc(84px + var(--safe-b)); }
}
@media (max-width: 899px) and (prefers-reduced-motion: reduce) {
  .sp-fab { transition: opacity var(--dur-2) linear; }
  html.scroll-down .sp-fab { transform: none; }
}
@media (min-width: 900px) {
  .sp-fab, body:has(> .tabbar) .sp-fab { inset-inline-start: 24px; inset-block-end: 24px; block-size: 48px; padding-inline: 16px 18px; }
  .sp-fab-l { display: inline; }
}
html[data-motion]:not([data-motion="0"]) .sp-fab { animation: sp-fab-in var(--dur-3) var(--spring) both; }
@keyframes sp-fab-in { from { opacity: 0; transform: scale(0.6); } }
@media print { .sp-fab { display: none !important; } }

/* notifications (notifications/, templates/notifications): header bell + sheet, inbox, settings, soft opt-in card --- */
.ntf-bell { position: relative; }
.ntf-badge { position: absolute; inset-block-start: 1px; inset-inline-end: -2px; min-inline-size: 18px; block-size: 18px; padding-inline: 4px;
  border-radius: 999px; background: var(--bad); color: #fff; font: 700 11px/18px var(--f-body); text-align: center;
  box-shadow: 0 0 0 2px var(--paper); pointer-events: none; }
html[data-motion]:not([data-motion="0"]) .ntf-badge:not([hidden]) { animation: ntf-pop var(--dur-3) var(--spring); }
@keyframes ntf-pop { from { transform: scale(0.4); opacity: 0; } }
.ntf-pop { inline-size: 360px; max-block-size: min(70dvh, 560px); overflow-y: auto; overscroll-behavior: contain; gap: 6px; }
.ntf-head { display: flex; align-items: center; justify-content: space-between; padding: 4px 6px 0; }
.ntf-head h2 { font-size: var(--fs-lg); }
.ntf-loading { padding: 18px 10px; text-align: center; }
.ntf-list { list-style: none; }
.ntf-item form { display: block; }
.ntf-item button, .ntf-kind { display: grid; grid-template-columns: 36px 1fr auto; gap: 12px; align-items: start; inline-size: 100%;
  padding: 10px 12px; border: 0; background: none; color: var(--ink); font: inherit; text-align: start; cursor: pointer; }
@media (hover: hover) and (pointer: fine) { .ntf-item button:hover { background: color-mix(in srgb, var(--ink) 5%, transparent); } }
.ntf-item button:active { background: color-mix(in srgb, var(--ink) 8%, transparent); }
.ntf-list > li + li::before, .ntf-kinds > li + li::before, .ntf-devs > li + li::before { content: ""; position: absolute; inset-block-start: 0;
  inset-inline: 60px 0; block-size: 0.5px; background: var(--sep); }
.ntf-ic { inline-size: 36px; block-size: 36px; border-radius: 10px; display: grid; place-items: center;
  background: color-mix(in srgb, var(--k, var(--indigo)) 14%, transparent); color: var(--k, var(--indigo)); }
.ntf-ic .ic { inline-size: 19px; block-size: 19px; color: inherit; }
.k-streak { --k: #e8590c; } .k-review { --k: var(--teal); } .k-support { --k: var(--ok); } .k-billing { --k: var(--indigo); }
.k-system { --k: var(--ink-2); } .k-content { --k: #a43fd1; }
.ntf-text { display: grid; gap: 2px; min-inline-size: 0; }
.ntf-top { display: flex; gap: 8px; align-items: baseline; justify-content: space-between; }
.ntf-title { font-weight: 600; line-height: var(--lh-title); }
.ntf-item:not(.unread) .ntf-title { font-weight: 500; }
.ntf-top time { flex: none; font-size: var(--fs-xs); color: var(--ink-2); }
.ntf-msg { font-size: var(--fs-sm); color: var(--ink-2); line-height: 1.6; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.ntf-page .ntf-msg { -webkit-line-clamp: 4; }
.ntf-dot { inline-size: 9px; block-size: 9px; border-radius: 50%; background: var(--indigo); margin-block-start: 8px; }
.ntf-item:not(.unread) button { grid-template-columns: 36px 1fr; }
.ntf-all { display: block; padding: 10px; text-align: center; font-weight: 600; font-size: var(--fs-sm); }
.ntf-empty { display: grid; justify-items: center; gap: 4px; padding: 28px 16px; text-align: center; }
.ntf-empty p { margin: 0; }
.ntf-empty-ic { inline-size: 52px; block-size: 52px; border-radius: 50%; display: grid; place-items: center; background: var(--tint); color: var(--indigo); margin-block-end: 6px; }
.ntf-empty-ic .ic, .ntf-device-ic .ic, .ntf-prompt-ic .ic { inline-size: 24px; block-size: 24px; }
.ntf-page, .ntf-settings { max-inline-size: 680px; }
.ntf-settings { display: grid; gap: 28px; }
.ntf-group { display: grid; gap: 8px; }
.ntf-group-h { font-size: var(--fs-xs); font-weight: 600; color: var(--ink-2); padding-inline: 14px; }
.ntf-foot { padding-inline: 14px; margin: 4px 0 0; }
.ntf-kinds { list-style: none; }
.ntf-kind { cursor: pointer; align-items: center; }
.ntf-kind .ntf-text b { font-weight: 600; }
input.ntf-switch { appearance: none; inline-size: 51px; block-size: 31px; margin: 0; border-radius: 999px; position: relative; cursor: pointer;
  background: color-mix(in srgb, var(--ink) 16%, transparent); transition: background-color var(--dur-2) var(--ease-std); }
input.ntf-switch::after { content: ""; position: absolute; inset-block-start: 2px; inset-inline-start: 2px; inline-size: 27px; block-size: 27px;
  border-radius: 50%; background: #fff; box-shadow: 0 2px 4px rgb(0 0 0 / 0.2); transition: transform var(--dur-3) var(--spring); }
input.ntf-switch:checked { background: var(--indigo); }
input.ntf-switch:checked::after { transform: translateX(-20px); }
input.ntf-switch:focus-visible { outline: 2px solid var(--indigo); outline-offset: 2px; }
.ntf-device { display: grid; grid-template-columns: auto 1fr auto; gap: 12px; align-items: center; }
.ntf-device > .btn + .btn { grid-column: 3; }
.ntf-device-ic, .ntf-prompt-ic { inline-size: 44px; block-size: 44px; border-radius: 12px; display: grid; place-items: center;
  background: linear-gradient(135deg, var(--brand-a), var(--brand-b)); color: #fff; }
.ntf-device-text { display: grid; gap: 2px; }
.ntf-device-text p { margin: 0; }
.ntf-dev-row { display: flex; gap: 12px; align-items: center; justify-content: space-between; padding: 10px 12px; }
.ntf-devs > li { padding-inline-start: 0; }
.ntf-devs > li + li::before { inset-inline-start: 12px; }
.ntf-off { max-inline-size: 460px; margin-inline: auto; }
.ntf-prompt { display: grid; grid-template-columns: auto 1fr; gap: 12px 14px; align-items: start; }
.ntf-prompt:not([hidden]) { animation: ntf-in var(--dur-3) var(--ease-out); }
html[data-motion="0"] .ntf-prompt { animation: none; }
@keyframes ntf-in { from { opacity: 0; transform: translateY(8px); } }
.ntf-prompt h2 { font-size: var(--fs-md); margin: 0 0 2px; }
.ntf-prompt p { margin: 0; }
.ntf-prompt-hour { display: inline-flex; gap: 8px; align-items: center; margin-block-start: 10px; font-size: var(--fs-sm); }
.ntf-prompt-hour select { inline-size: auto; min-block-size: 36px; font-size: var(--fs-base); } /* 16px: smaller fields zoom the page on focus */
.ntf-prompt-actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 8px; }
.ntf-prompt-actions .btn { flex: 1 1 140px; }
@media (max-width: 899px) {
  .ntf-pop { inline-size: auto; max-block-size: calc(100dvh - var(--safe-t) - 72px); }
  .ntf-item button { padding-inline: 14px; }
  .ntf-device { grid-template-columns: auto 1fr; }
  .ntf-device > .btn { grid-column: 1 / -1; }
}
/* an open header sheet (bell, user menu) must cover the tab bar (z 55) and the support button (z 54): the sticky header
   is their stacking context (z 50), so lift it while one is open */
.site-header:has(details.menu[open]) { z-index: 80; }
/* a scrolled header blurs what is behind it (app.css .scrolled); a backdrop-filter makes the header the containing block
   of its position:fixed children, which pinned the menu sheet to the header's bottom edge, off screen. While a sheet is
   open the scrim covers the header anyway. */
@media (max-width: 899px) { .site-header:has(details.menu[open]) { -webkit-backdrop-filter: none; backdrop-filter: none; } }
/* signed-in phones have three header icons (account, bell, theme ≈ 112px at the inline end): keep the compact title
   clear of them (the brand at the start hides while the title shows) */
@media (max-width: 899px) { .site-header:has(.ntf-menu) .nav-title { inset-inline: 20px 206px; } }  /* + the فا|EN pill (66px) */
/* signed-out phones: menu, «ورود» and theme (≈ 150px at the inline end) */
@media (max-width: 899px) { .site-header:has(.nav-login) .nav-title { inset-inline: 20px 230px; } }

/* links and sections that only make sense on the website (app download, install guide) never show inside the app */
html.in-app [data-web-only] { display: none !important; }

/* «نسخه‌ی جدید اپ آماده است» (templates/core/_app_update.html; the direct-APK app only): a resting card at the top of
   <main>, in the page flow, so it never covers the header or the tab bar */
.app-update-wrap { margin-block: 12px 4px; }
.app-update { display: grid; grid-template-columns: auto 1fr; gap: 12px 14px; align-items: start; padding: 14px 16px 12px;
  border-radius: var(--r-lg); background: var(--card); box-shadow: var(--e1);
  transition: opacity var(--dur-2) var(--ease-std), transform var(--dur-2) var(--ease-std); }
.app-update.is-leaving { opacity: 0; transform: translateY(-6px) scale(0.98); }
html[data-motion="0"] .app-update { transition: none; }
.app-update-ic { inline-size: 40px; block-size: 40px; border-radius: 11px; display: grid; place-items: center;
  background: linear-gradient(135deg, var(--brand-a), var(--brand-b)); color: #fff; }
.app-update-ic .ic { inline-size: 22px; block-size: 22px; }
.app-update-text { display: grid; gap: 2px; min-inline-size: 0; align-self: center; }
.app-update h2 { margin: 0; font-size: var(--fs-md); font-weight: 700; line-height: var(--lh-title); }
.app-update-text p { margin: 0; font-size: var(--fs-sm); line-height: 1.6; color: var(--ink-2); }
.app-update-actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 8px; }
.app-update-actions .btn { flex: 1 1 auto; white-space: nowrap; }
.app-update-actions .btn-primary { flex-grow: 3; }  /* one row when it fits (≈400px+), else two full-width capsules */
.app-update-help { grid-column: 1 / -1; margin: 0; font-size: var(--fs-xs); line-height: 1.7; color: var(--ink-2); }
.app-update-copy { position: relative; display: inline-flex; gap: 4px; align-items: center; padding: 0 2px; border: 0; background: none;
  font: inherit; font-weight: 650; color: var(--indigo); cursor: pointer; touch-action: manipulation; -webkit-user-select: none; user-select: none; }
.app-update-copy::before { content: ""; position: absolute; inset: -14px -6px; } /* 44px tall touch target */
.app-update-copy .ic { inline-size: 14px; block-size: 14px; }
.app-update-copy:active { opacity: 0.6; }
.app-update-copy:focus-visible { outline: 2px solid var(--indigo); outline-offset: 2px; border-radius: 4px; }
.app-update-status:not(:empty) { font-weight: 650; color: var(--ok); }
/* below APP_MIN_VERSION: cannot be put off, so it reads as a warning (saffron tile, a hairline accent ring) */
.app-update.is-forced { box-shadow: var(--e1), inset 0 0 0 1px color-mix(in srgb, var(--saffron) 70%, transparent); }
.app-update.is-forced .app-update-ic { background: var(--saffron); color: #1d1d1f; }
@media (min-width: 760px) {
  .app-update { grid-template-columns: auto 1fr auto; align-items: center; }
  .app-update-actions { grid-column: 3; grid-row: 1; flex-wrap: nowrap; }
  .app-update-actions .btn { flex: none; }
  .app-update-help { grid-column: 2 / -1; }
}
/* the rating card (templates/accounts/_review_prompt.html) reuses the card above; it sits inside the finished-lesson card */
.review-prompt { margin-block: 14px 0; text-align: start; }
.review-prompt.is-leaving { opacity: 0; transform: translateY(-6px) scale(0.98); }
@media print { .app-update-wrap, .review-prompt { display: none !important; } }
#main[tabindex="-1"]:focus { outline: none; } /* focus parks here after «بعداً» removes the card */

/* ---- the English site (dir="ltr", core.middleware.UILanguageMiddleware) ----------------------------------------------
   A few components pin `direction: rtl` (the top layer of <dialog>/popovers, charts that read right to left) or grow from
   the right. On the English site they follow the page instead, so the support sheet opens on the same side as its button
   and progress fills from the left. Persian content inside them keeps its own dir. */
html[dir="ltr"] .sp-sheet, html[dir="ltr"] .pop, html[dir="ltr"] .start-chip, html[dir="ltr"] .weekbars { direction: ltr; }
html[dir="ltr"] .bar > i, html[dir="ltr"] .mp-turn i { transform-origin: left center; }
@media (min-width: 700px) { html[dir="ltr"][data-motion]:not([data-motion="0"]) .sp-sheet[open] { transform-origin: bottom left; } }

/* phones with the tab bar: the floating support button would sit on top of content and the tab bar; support is in the
   «من» sheet instead (base.html .menu-support), and a new reply shows as a dot on «من» */
.menu-support { position: relative; }
.menu-dot, .tab-dot { inline-size: 8px; block-size: 8px; border-radius: 50%; background: var(--bad); flex: none; }
.tab-dot { position: absolute; inset-block-start: 6px; inset-inline-end: calc(50% - 18px); box-shadow: 0 0 0 2px var(--paper); }
.glist > a.menu-support { display: none; }
@media (max-width: 899px) {
  body:has(> .tabbar) .sp-fab { display: none; }
  body:has(> .tabbar) .glist > a.menu-support { display: flex; }
  /* what the tab bar already offers is not repeated in the «من» sheet (one way to each place) */
  body:has(> .tabbar) .glist > a.in-tabbar { display: none; }
}

/* page changes feel like an app (Chrome / Android WebView 126+): the header and the tab bar stay put while the content
   cross-fades and rises a few pixels. Same-document transitions (the theme toggle) keep the browser's default fade. */
@view-transition { navigation: auto; types: page; }
.site-header { view-transition-name: site-header; }
.tabbar { view-transition-name: tabbar; }
html:active-view-transition-type(page)::view-transition-old(root) { animation: vt-page-out 140ms var(--ease-std) both; }
html:active-view-transition-type(page)::view-transition-new(root) { animation: vt-page-in 260ms var(--ease-std) both; }
@keyframes vt-page-out { to { opacity: 0; } }
@keyframes vt-page-in { from { opacity: 0; transform: translateY(10px); } }
html[data-motion="0"]::view-transition-group(*), html[data-motion="0"]::view-transition-old(*), html[data-motion="0"]::view-transition-new(*) { animation: none !important; }
@media (prefers-reduced-motion: reduce) { @view-transition { navigation: none; } }

/* dashboard «پیشرفت من» (templates/learn/dashboard.html): the numbers, folded under one row; open state remembered */
.dash-more { padding: 0; overflow: hidden; }
.dash-more > summary { display: flex; align-items: center; gap: 12px; min-block-size: 60px; padding: 14px 18px; cursor: pointer; list-style: none;
  -webkit-tap-highlight-color: transparent; }
.dash-more > summary::-webkit-details-marker { display: none; }
.dash-more > summary:focus-visible { outline: 2px solid var(--indigo); outline-offset: -2px; border-radius: inherit; }
.dm-head { display: grid; gap: 2px; flex: 1; min-inline-size: 0; }
.dm-head h2 { margin: 0; }
.dm-head small { font-size: var(--fs-xs); line-height: 1.6; }
.dm-chev { inline-size: 20px; block-size: 20px; flex: none; color: var(--ink-2); transition: transform var(--dur-2) var(--spring); }
.dash-more[open] .dm-chev { transform: rotate(180deg); }
.dm-grid { display: grid; gap: 0; padding: 0 18px 8px; }
.dm-block { padding-block: 16px; border-block-start: 0.5px solid var(--sep); min-inline-size: 0; }
.dm-block h3 { margin: 0 0 12px; font-size: var(--fs-md); }
@media (min-width: 760px) { .dm-grid { grid-template-columns: 1fr 1fr; column-gap: 28px; } }
html[data-motion]:not([data-motion="0"]) .dash-more[open] .dm-grid { animation: dm-in var(--dur-3) var(--ease-std); }
@keyframes dm-in { from { opacity: 0; transform: translateY(-6px); } }

/* ---- «اولترا» (Plan kind "family", the top tier; docs/PRICING.md) ---------------------------------------------------
   One look everywhere: a near-black surface in both themes (tokens redefined like .on-dark, so prices, buttons and the
   coupon field inside turn dark without their own rules), a thin gold/indigo edge, and a gold ✦ mark
   (billing/_ultra_mark.html). The edge's light travels slowly round the card at motion tier 2-3 only: an oversized
   conic gradient that rotates (transform only) inside a 1.5px ring mask; tiers 0-1 and reduced motion keep the static
   ring. Ring and sheen are absolutely positioned and clipped, so nothing shifts the layout or the page width. */
:root { --ultra-gold: #946a12; }  /* the mark on light surfaces (3:1+ on --paper and --card) */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --ultra-gold: #e7c27a; } }
:root[data-theme="dark"] { --ultra-gold: #e7c27a; }
.ultra-mark { display: inline-block; inline-size: 0.62em; block-size: 0.62em; vertical-align: 0.28em; fill: currentColor; color: var(--ultra-gold); flex: none; }
.ultra-pill { display: inline-flex; align-items: center; gap: 5px; padding: 1px 10px; border-radius: 999px; background: #111117; color: #f7e2ae;
  font-weight: 700; font-size: var(--fs-xs); line-height: 1.8; box-shadow: inset 0 0 0 1px rgb(231 194 122 / 0.4); white-space: nowrap; }
.ultra-pill .ultra-mark { color: #f7e2ae; vertical-align: 0; }
.ultra-surface {
  --paper: #0b0b10; --paper-2: #24242d; --card: #121219; --ink: #f5f5f7; --ink-2: #b6b6c3; --hair: #35353f;
  --sep: rgb(255 255 255 / 0.12); --indigo: #a9abff; --on-indigo: #0b0b10; --tint: rgb(169 171 255 / 0.16);
  --ok: #5ad893; --saffron: #ffcc5c; --ultra-gold: #f2d38f;
  --ultra-bg: radial-gradient(130% 60% at 50% 0%, rgb(104 106 255 / 0.2), transparent 62%), linear-gradient(180deg, #15151d, #0c0c11);
  --ultra-shadow: 0 0 0 0.5px rgb(231 194 122 / 0.25), 0 2px 6px rgb(0 0 0 / 0.16), 0 26px 50px -26px rgb(40 38 130 / 0.6);
  color-scheme: dark; color: var(--ink); background: var(--ultra-bg); box-shadow: var(--ultra-shadow); isolation: isolate;
}
.ultra-surface .btn-primary { background: linear-gradient(180deg, #f6dfa6, #e1b860); color: #1a1407;
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.55), 0 8px 20px -10px rgb(225 184 96 / 0.7); }
@media (hover: hover) and (pointer: fine) { .ultra-surface .btn-primary:hover { filter: brightness(1.05); } }
.ultra-surface .btn-primary:focus-visible { outline: 2px solid #f6dfa6; outline-offset: 3px; }
.ultra-sheen { position: absolute; inset: 0; border-radius: inherit; padding: 1.5px; pointer-events: none; overflow: hidden;
  background: linear-gradient(155deg, rgb(247 226 174 / 0.75), rgb(142 144 255 / 0.45) 40%, rgb(255 255 255 / 0.1) 68%, rgb(231 194 122 / 0.55));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); }
.ultra-sheen::before { content: ""; position: absolute; left: 50%; top: 50%; width: 320%; aspect-ratio: 1; opacity: 0;
  transform: translate(-50%, -50%) rotate(0turn);
  background: conic-gradient(transparent 0 58%, rgb(142 144 255 / 0.95) 68%, #fff1cc 76%, #e7c27a 80%, transparent 90% 100%); }
html[data-motion="2"] .ultra-sheen::before, html[data-motion="3"] .ultra-sheen::before { opacity: 1; animation: ultra-sheen 10s linear infinite; }
@keyframes ultra-sheen { to { transform: translate(-50%, -50%) rotate(1turn); } }
@media (prefers-reduced-motion: reduce) { .ultra-sheen::before { animation: none !important; opacity: 0 !important; } }
@media (prefers-contrast: more) { .ultra-sheen { background: #e7c27a; } .ultra-surface { --ink-2: #d4d4de; } }
@media print { .ultra-sheen { display: none; } }
.plans3 .plan.ultra-surface { background: var(--ultra-bg); box-shadow: var(--ultra-shadow); }  /* home card of an «اولترا» plan */

/* «get the app» (core/app_download.py): store badges, the phone banner, footer badges, the app's feature list ---------- */
/* badges are ours (no official store artwork): black in both themes with a hairline that shows on a dark page */
.appbadges { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 10px; }
.appbadge { display: inline-flex; align-items: center; gap: 10px; min-block-size: 52px; padding-block: 7px; padding-inline: 14px 18px;
  border-radius: 14px; background: #101012; color: #fff; text-decoration: none; box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.16);
  touch-action: manipulation; -webkit-user-select: none; user-select: none; transition: transform var(--dur-1) var(--ease-out), background-color var(--dur-1); }
.appbadge:active { transform: scale(0.97); }
@media (hover: hover) and (pointer: fine) { .appbadge:hover { background: #2a2a2e; } }
.appbadge:focus-visible { outline: 2px solid var(--indigo); outline-offset: 3px; }
.appbadge-ic { display: grid; place-items: center; inline-size: 28px; block-size: 28px; flex: none; }
.appbadge-ic svg { inline-size: 100%; block-size: 100%; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.appbadge-bazaar .appbadge-ic { color: #8be07a; }
.appbadge-myket .appbadge-ic { color: #7cc4ff; }
.appbadge-apk .appbadge-ic { color: #5fe0d2; }
.appbadge-t { display: grid; line-height: 1.3; text-align: start; }
.appbadge-t small { font-size: var(--fs-2xs); opacity: 0.78; }
.appbadge-t b { font-size: var(--fs-base); font-weight: 700; }
.appbadges-sm { gap: 8px; }
.appbadges-sm .appbadge { min-block-size: 44px; padding-block: 5px; padding-inline: 10px 14px; border-radius: 12px; gap: 8px; }
.appbadges-sm .appbadge-ic { inline-size: 22px; block-size: 22px; }
.appbadges-sm .appbadge-t b { font-size: var(--fs-sm); }
.appbadges-lg .appbadge { min-block-size: 60px; padding-inline: 16px 22px; }
.appbadges-lg .appbadge-t b { font-size: var(--fs-md); }
.qr { display: block; border-radius: 8px; }

.foot-app { margin-block-start: 18px; }
.foot-app h2 { margin-block-end: 8px; }
.foot-app h2 a { color: inherit; text-decoration: none; }
@media (hover: hover) and (pointer: fine) { .foot-app h2 a:hover { text-decoration: underline; text-underline-offset: 3px; } }

/* the phone banner: in the flow above the sticky header, decided before first paint (no shift); a hint, not an interstitial */
.appbar { display: flex; align-items: center; gap: 10px; min-block-size: 60px; position: relative; z-index: 51;
  padding-block: calc(8px + var(--safe-t)) 8px; padding-inline: max(8px, var(--safe-l)) max(12px, var(--safe-r));
  background: var(--card); border-block-end: 0.5px solid var(--sep); font-size: var(--fs-sm); }
.appbar[hidden] { display: none; }
html.appbar-wait .appbar { visibility: hidden; }
.appbar:not([data-os="android"]) .for-android, .appbar:not([data-os="ios"]) .for-ios { display: none; }
.appbar-x { position: relative; display: grid; place-items: center; inline-size: 32px; block-size: 32px; flex: none; border: 0; border-radius: 50%;
  background: transparent; color: var(--ink-2); cursor: pointer; touch-action: manipulation; }
.appbar-x::before { content: ""; position: absolute; inset: -6px; }
.appbar-x .ic { inline-size: 18px; block-size: 18px; }
.appbar-x:active { background: var(--paper-2); }
.appbar-ic { display: grid; place-items: center; inline-size: 42px; block-size: 42px; flex: none; border-radius: 10px; background: var(--paper);
  box-shadow: inset 0 0 0 0.5px var(--sep); }
.appbar-ic .brand-mark { inline-size: 30px; block-size: 30px; }
.appbar-t { flex: 1; min-inline-size: 0; margin: 0; display: grid; line-height: 1.45; }
.appbar-t b { font-weight: 700; color: var(--ink); }
.appbar-t small { font-size: var(--fs-2xs); color: var(--ink-2); }
.appbar .btn { flex: none; }

/* what the app adds (home #app section and /app/) */
.appsec-feats { list-style: none; margin: 0 0 24px; padding: 0; display: grid; gap: 16px 24px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr)); }
.appsec-feats li { display: flex; gap: 12px; align-items: flex-start; }
.appsec-feats .ic { flex: none; inline-size: 40px; block-size: 40px; padding: 9px; border-radius: 12px; background: var(--tint); color: var(--indigo); }
.appsec-feats b { display: block; font-weight: 650; }
.appsec-feats small { display: block; color: var(--ink-2); font-size: var(--fs-sm); line-height: 1.7; }
/* the one-time Plus trial offer (templates/billing/_trial_offer.html) */
.trial-offer { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px;
  border-color: var(--teal); background: linear-gradient(135deg, color-mix(in srgb, var(--teal) 10%, var(--card)), var(--card)); }
.trial-offer h2 { display: flex; align-items: center; gap: 6px; margin: 0; font-size: var(--fs-lg); }

/* dashboard: the learner's study programme (learn/programmes.py) */
.prog-card { display: grid; gap: 8px; }
.prog-card h2 { display: flex; align-items: center; gap: 6px; font-size: var(--fs-lg); margin: 0; }
.prog-cta { display: flex; align-items: center; gap: 12px; color: inherit; text-decoration: none; }
.prog-cta small { display: block; color: var(--ink-2); }
.rv-art { display: block; inline-size: 96px; block-size: 96px; margin-inline: auto; } /* review card picture (Word.art) */
