/* Accessibility floor (spec 9.5, NF-7): last stylesheet, so it wins over the
   three styles. Field borders reach 3:1 against the card they sit on, and the
   audit in test/contrast.test.mjs keeps the text colours at 4.5:1. */
:root {
  --field-line: color-mix(in srgb, var(--text) 52%, var(--panel));
}
:root[data-style]
  input:not(
    [type="radio"],
    [type="checkbox"],
    [type="range"],
    [type="file"],
    :focus-visible
  ),
:root[data-style] select:not(:focus-visible),
:root[data-style] textarea:not(:focus-visible),
:root[data-style] .input:not(:focus-visible),
:root[data-style] .select:not(:focus-visible),
:root[data-style] .textarea:not(:focus-visible) {
  border-color: var(--field-line);
}
:root[data-style][data-theme="light"][data-style="neon"] .btn--primary {
  background: linear-gradient(
    135deg,
    var(--accent),
    color-mix(in srgb, var(--accent-2) 65%, #000)
  );
}

.words-tabs {
  margin-bottom: 14px;
}
.words-tabs button {
  flex: 1 1 0;
}
@media (max-width: 767px) {
  .words-tabs {
    display: flex;
    width: 100%;
  }
  .words-tabs button {
    min-height: 44px;
    font-size: 13px;
  }
}

/* Homework / Quests / Speaking on a phone: three equal parts; a long label
   (in Russian "Разговорная практика") wraps instead of hiding behind a scroll. */
@media (max-width: 560px) {
  :root .task-tabs.task-tabs {
    display: flex;
    width: 100%;
  }
  :root .task-tabs.task-tabs > button {
    flex: 1 1 0;
    min-width: 0;
    padding: 6px 8px;
    white-space: normal;
    line-height: 1.15;
    text-align: center;
    overflow-wrap: anywhere;
  }
}

/* Phone (spec 9.3, D-3): every control is at least 44 px so a thumb hits it. */
@media (max-width: 767px) {
  /* the slider is drawn as a field pill, so it gets the field height */
  input[type="range"] {
    min-height: 44px;
  }
  button:not(.sr-only),
  a.btn,
  [role="button"],
  summary,
  select,
  .input,
  .field input:not([type="checkbox"], [type="radio"], [type="range"]) {
    min-height: 44px;
  }
  button:not(.sr-only, .chip--button, .nav-item, .seg),
  a.btn {
    min-width: 44px;
  }
  /* menu rows and the round buttons of the top bar */
  .nav-item {
    min-height: 44px;
  }
  :root[data-style] .topbar :is(.icon-btn, .quick-control) {
    width: 44px;
    height: 44px;
  }
  /* the credit pill keeps its small look and reaches 44 px with an invisible
     hit area */
  .credit-link {
    position: relative;
  }
  .credit-link::after {
    content: "";
    position: absolute;
    inset: -8px -4px;
  }
}

/* The dictation button sits inside a field, so it keeps its 30 px look and
   reaches 44 px with an invisible hit area instead of covering the border. */
@media (max-width: 767px) {
  :root .voice-btn {
    min-width: 30px;
    min-height: 30px;
    width: 30px;
    height: 30px;
  }
  :root .voice-btn::after {
    content: "";
    position: absolute;
    inset: -7px;
  }
}

@media (max-width: 767px) {
  :root .icon-btn,
  :root .icon-btn--sm {
    width: 44px;
    height: 44px;
  }
  :root .study-status-control .seg {
    min-height: 44px;
  }
}

/* Rows with a variable number of parts (icon, text, badges, actions) sit on
   one line when they fit and wrap the actions under the text when they do not. */
.list-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
}
.list-row > .list-row-icon {
  flex: none;
}
.list-row > .list-row-copy {
  flex: 1 1 200px;
  min-width: 0;
}
.list-row > .table-actions {
  margin-left: auto;
}
.list-row-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
}

/* Progress: the weekly chart (spec 7, 8 weeks) */
.week-chart {
  display: grid;
  grid-template-columns: repeat(8, minmax(0, 1fr));
  align-items: end;
  gap: 8px;
  height: 160px;
  margin-top: 12px;
}
.week-bar {
  position: relative;
  display: grid;
  grid-template-rows: 18px minmax(0, 1fr) 20px;
  height: 100%;
  min-width: 0;
}
.week-value,
.week-label {
  text-align: center;
  color: var(--muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.week-fill {
  align-self: end;
  width: 100%;
  min-height: 3px;
  border-radius: 6px 6px 0 0;
  background: linear-gradient(
    180deg,
    var(--accent),
    color-mix(in srgb, var(--accent-2, var(--accent)) 70%, var(--accent))
  );
  transform-origin: bottom;
  transition:
    transform 0.3s var(--spring, ease),
    filter 0.2s;
  animation: week-grow 0.8s calc(var(--w, 0) * 70ms + 0.15s) var(--ease, ease)
    backwards;
}
.week-bar:last-child .week-fill {
  background: linear-gradient(180deg, var(--accent-strong), var(--accent) 80%);
  box-shadow: 0 0 18px -4px var(--accent);
}
.week-bar:hover .week-fill {
  transform: scaleY(1.04);
  filter: brightness(1.15);
}
.week-chart.is-empty .week-fill {
  opacity: 0.35;
}
.week-chart-empty {
  margin: 10px 0 0;
  color: var(--muted);
  font-size: 14px;
  text-align: center;
}
@keyframes week-grow {
  from {
    transform: scaleY(0);
    opacity: 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .week-fill {
    animation: none;
  }
}
:root[data-anim="off"] .week-fill {
  animation: none;
}
.xp-log {
  display: grid;
  gap: 8px;
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
}
.xp-log li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  padding: 8px 12px;
  border: 1px solid var(--line-soft);
  border-radius: var(--r-sm);
}
.xp-log li.is-negative strong {
  color: var(--danger);
}
.xp-log li strong {
  font-variant-numeric: tabular-nums;
}
.lesson-links {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}
.lesson-link {
  justify-content: center;
}

/* The teacher's dashboard: the student table needs the full width until there is room for both columns */
@media (max-width: 1279px) {
  #view-dashboard .grid--wide {
    grid-template-columns: minmax(0, 1fr);
  }
}
.list-row-subtitle {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 10px;
}
.list-row-subtitle > span + span::before {
  content: none;
}
.task-tabs button {
  white-space: nowrap;
}
.task-tabs {
  max-width: 100%;
  overflow-x: auto;
}
.nav-badge {
  margin-left: auto;
  min-width: 22px;
  padding: 1px 7px;
  border-radius: var(--r-pill);
  color: var(--on-accent);
  background: var(--accent);
  font-size: 12px;
  font-weight: 700;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.nav-badge[hidden] {
  display: none;
}
/* Twelve workspace tabs: they wrap instead of hiding behind a scroll */
.workspace-tabs {
  flex-wrap: wrap;
  overflow: visible;
}
.settings-block {
  align-content: start;
}
/* label above value, never side by side on one line */
#view-profile .form-grid > div {
  display: grid;
  gap: 4px;
  align-content: start;
  min-width: 0;
}
#view-profile .form-grid strong {
  font-size: 15px;
  overflow-wrap: anywhere;
}
.photo-caption {
  margin: 10px 0 0;
  color: var(--muted);
}

/* Auth notice: readable block with room, not a bare strip under the link. */
#authNotice {
  margin-top: 10px;
  padding: 9px 12px;
  border: 1px solid transparent;
  border-radius: 12px;
  font-size: 13px;
  line-height: 1.4;
}
#authNotice:empty {
  display: none;
}
#authNotice.status-pill--danger {
  display: block;
}

/* Forgot password is two steps: email first, then code + new password. */
#forgotForm:not([data-step="reset"]) label[for="forgotCode"],
#forgotForm:not([data-step="reset"]) label[for="forgotPassword"] {
  display: none;
}
#forgotForm[data-step="reset"] #forgotEmail {
  opacity: 0.7;
  pointer-events: none;
}

/* The drawer close button exists only where the sidebar is a drawer (phone). */
.sidebar .sidebar-close {
  display: none;
}
@media (max-width: 767px) {
  .sidebar .sidebar-close {
    position: absolute;
    top: 14px;
    right: 13px;
    display: grid;
    place-items: center;
  }
}

/* Decorative hero captions are English-only and clip on a narrow screen. */
@media (max-width: 767px) {
  .hero--home::before,
  .hero--teacher::before,
  .hero--admin::before {
    display: none;
  }
}

/* A read-only value must not look editable. */
input[readonly]:not([type="checkbox"]):not([type="radio"]) {
  background: color-mix(in srgb, var(--muted) 8%, transparent);
  color: var(--muted);
  cursor: default;
}

/* Optional card fields fold away so the form stays short. */
.card-more {
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 0 14px;
}
.card-more > summary {
  display: flex;
  align-items: center;
  min-height: 44px;
  color: var(--accent-strong, var(--accent));
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}
.card-more > summary::-webkit-details-marker {
  display: none;
}
.card-more > summary::after {
  content: "";
  width: 7px;
  height: 7px;
  margin-left: auto;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform 160ms ease;
}
.card-more[open] > summary::after {
  transform: rotate(-135deg);
}
.card-more-body {
  display: grid;
  gap: 12px;
  padding-bottom: 14px;
}
@media (prefers-reduced-motion: reduce) {
  .card-more > summary::after {
    transition: none;
  }
}
html[data-anim="off"] .card-more > summary::after {
  transition: none;
}

/* Inline blanks in a sentence look like the other fields, just shorter. */
.fill-blank {
  min-height: 38px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm, 10px);
  color: var(--text);
  background: var(--field, var(--panel));
  font: inherit;
  outline: 0;
}
.fill-blank:focus-visible {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}

/* A view takes programmatic focus on navigation (for screen readers); it is not a control, so no ring. */
.app-view:focus,
.app-view:focus-visible,
[data-view-panel]:focus,
[data-view-panel]:focus-visible {
  outline: none;
}

/* The page for an address that is missing or not allowed. */
.empty-state--page {
  min-height: 52vh;
  justify-content: center;
  align-content: center;
  justify-items: center;
  text-align: center;
  gap: 10px;
}
.empty-state--page .btn {
  margin-top: 8px;
}

/* Account rows in Settings: breathing room and a thin rule between them. */
.setting-list {
  display: grid;
  gap: 0;
  margin-top: 14px;
}
.setting-list > .setting-row {
  padding: 14px 0;
  border-top: 1px solid var(--line-soft, var(--line));
}
.setting-list > .setting-row > input.input,
.setting-list > .setting-row > select {
  max-width: 320px;
}
.setting-row .ui-select:has(#settingsTimezone) {
  flex: 0 0 min(260px, 100%);
  min-width: 200px;
}

/* Phone: a setting with a wide control puts the control under its label. */
@media (max-width: 480px) {
  .setting-list > .setting-row,
  .setting-row:has(#settingsTimezone) {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 10px;
    align-items: start;
  }
  .setting-list > .setting-row > button,
  .setting-list > .setting-row > input.input {
    width: 100%;
    max-width: none;
  }
  .setting-row .ui-select:has(#settingsTimezone) {
    flex: none;
    width: 100%;
  }
}

/* Teacher's "Lesson" block: one line above the tabs, the fields open on demand. */
.lesson-block {
  display: block;
  padding: 0 16px;
}
.lesson-block-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  min-height: 52px;
  padding: 8px 0;
  cursor: pointer;
  list-style: none;
}
.lesson-block-summary::-webkit-details-marker {
  display: none;
}
.lesson-block-summary h3 {
  margin: 0;
  color: var(--faint);
  font-size: 12px;
  font-weight: 650;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.lesson-block-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.lesson-block-links .lesson-link {
  min-height: 36px;
  padding: 0 14px;
  font-size: 13px;
}
.lesson-block-edit {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--accent-strong, var(--accent));
  font-size: 13px;
  font-weight: 600;
}
.lesson-block-edit::after {
  content: "";
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform 160ms ease;
}
.lesson-block[open] .lesson-block-edit::after {
  transform: rotate(-135deg);
}
.lesson-block-form {
  display: grid;
  gap: 10px;
  padding: 4px 0 16px;
}
html[data-anim="off"] .lesson-block-edit::after {
  transition: none;
}
@media (prefers-reduced-motion: reduce) {
  .lesson-block-edit::after {
    transition: none;
  }
}

/* Keyboard users jump past the sidebar; the link shows only while focused. */
.skip-link {
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: 400;
  min-height: 44px;
  padding: 0 18px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  color: var(--text);
  background: var(--panel);
  font-weight: 600;
  transform: translateY(-160%);
}
.skip-link:focus-visible {
  transform: none;
}
#content:focus {
  outline: none;
}

/* ---- Sidebar rail (laptop and tablet) and the phone drawer button ---- */
.menu-trigger {
  display: none;
}
@media (max-width: 767px) {
  .menu-trigger {
    display: inline-grid;
  }
  .sidebar-collapse {
    display: none;
  }
}
@media (min-width: 768px) {
  .app-shell {
    transition: grid-template-columns 200ms ease;
  }
  .sidebar {
    transition: width 200ms ease;
    overflow: hidden;
  }
  html.sidebar-collapsed {
    --sidebar: 76px;
  }
  html.sidebar-collapsed .sidebar {
    padding-inline: 10px;
    align-items: stretch;
  }
  html.sidebar-collapsed
    :is(
      .brand-copy,
      .credit-link span,
      .nav-item-label,
      .nav-group-label,
      .account-copy,
      #accountMenuButton,
      #sidebarLogout span
    ) {
    display: none;
  }
  html.sidebar-collapsed .sidebar-brand-row,
  html.sidebar-collapsed .credit-link,
  html.sidebar-collapsed .sidebar-collapse,
  html.sidebar-collapsed .nav-item,
  html.sidebar-collapsed #sidebarLogout {
    justify-content: center;
  }
  html.sidebar-collapsed .nav-item {
    padding-inline: 0;
  }
  html.sidebar-collapsed .credit-link {
    padding-inline: 0;
  }
  html.sidebar-collapsed .account-chip {
    justify-content: center;
    padding-inline: 0;
  }
  html.sidebar-collapsed .sidebar-collapse .mono {
    letter-spacing: 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .app-shell,
  .sidebar {
    transition: none;
  }
}
html[data-anim="off"] .app-shell,
html[data-anim="off"] .sidebar {
  transition: none;
}

.sidebar-collapse {
  width: 44px;
  min-height: 36px;
  border-radius: 12px;
}
.sidebar-collapse .icon {
  width: 18px;
  height: 18px;
}

/* Sidebar group captions: readable size, and AA contrast in every style. */
:root[data-style] .nav-group-label {
  color: var(--muted);
  font-size: 11px;
}

/* Phone: the lesson links in the student's summary row and the filter chips are
   tapped with a thumb, so they get the full 44 px. */
@media (max-width: 767px) {
  .lesson-block-links .lesson-link,
  .check-chip {
    min-height: 44px;
  }
}

/* A tab strip that scrolls fades out on the side where more tabs are hidden,
   so a cut-off tab reads as "scroll for more" instead of a broken layout.
   tabs-fx.ts sets data-more-start / data-more-end; a strip that fits keeps
   its glow because no mask is applied. */
:is(.words-tabs, .workspace-tabs):is([data-more-start], [data-more-end]) {
  --fade-start: 0px;
  --fade-end: 0px;
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent 0,
    #000 var(--fade-start),
    #000 calc(100% - var(--fade-end)),
    transparent 100%
  );
  mask-image: linear-gradient(
    90deg,
    transparent 0,
    #000 var(--fade-start),
    #000 calc(100% - var(--fade-end)),
    transparent 100%
  );
}
:is(.words-tabs, .workspace-tabs)[data-more-start] {
  --fade-start: 40px;
}
:is(.words-tabs, .workspace-tabs)[data-more-end] {
  --fade-end: 40px;
}
