/*
  English Learning OS — the student shell.

  Top bar, phone tab bar, account menu, footer, and the display primitives that
  belong to the shell rather than to any one screen (rings, headline chips,
  section headers).

  Same two rules as base.css: tokens only, logical properties only.
*/


/* ── Page frame ─────────────────────────────────────────────────
   The body is a column so the footer sits at the bottom of a short page
   instead of floating in the middle of it. The bottom padding on the app
   shell is the phone tab bar's height plus the home-indicator inset; without
   it the last card on every screen is unreachable on an iPhone. */

.lx-body--app {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
}
.lx-body--app > .lx-main { flex: 1 0 auto; }

.lx-main {
  padding-block: var(--lx-sp-5) var(--lx-sp-7);
}
@media (max-width: 900px) {
  .lx-body--app { padding-block-end: calc(64px + env(safe-area-inset-bottom, 0px)); }
}


/* ── Top bar ────────────────────────────────────────────────────
   position: sticky rather than fixed. Fixed takes the bar out of flow, which
   means every page underneath needs a matching padding-top, and the two drift
   the moment the bar gains a second row. */

.lx-top {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--lx-z-sticky);
  background: var(--lx-surface);
  border-block-end: var(--lx-bw-hair) solid var(--lx-border);
  backdrop-filter: saturate(140%) blur(8px);
}

.lx-top-in {
  display: flex;
  align-items: center;
  gap: var(--lx-sp-4);
  min-block-size: 60px;
}

.lx-brand {
  display: inline-flex; align-items: center; gap: var(--lx-sp-2);
  color: var(--lx-text); font-weight: 800; font-size: var(--lx-fs-lg);
  text-decoration: none; flex: none;
}
.lx-brand:hover { color: var(--lx-text); text-decoration: none; }
/* .lx-brand-mark moved to base.css — the admin bar emits it too. */
@media (max-width: 640px) { .lx-brand-txt { display: none; } }

/* The desktop nav. Hidden on phones, where the bottom tab bar takes over —
   a ten-item horizontal scroller in a 60px bar is not navigation. */
.lx-nav { display: flex; gap: var(--lx-sp-1); overflow-x: auto; scrollbar-width: none; }
.lx-nav::-webkit-scrollbar { display: none; }
@media (max-width: 900px) { .lx-nav { display: none; } }

/* The current item is marked twice — a fill AND a rule under it. Colour alone
   is one signal, and it is the signal a colour-blind reader is least likely
   to receive on a ten-item bar where every other item is also a word. */
.lx-nav-a {
  position: relative;
  padding: var(--lx-sp-2) var(--lx-sp-3);
  border-radius: var(--lx-r-md);
  color: var(--lx-text-2);
  font-weight: var(--lx-fw-semi); font-size: var(--lx-fs-sm);
  white-space: nowrap; text-decoration: none;
  transition: background var(--lx-t-fast) var(--lx-ease), color var(--lx-t-fast) var(--lx-ease);
}
.lx-nav-a:hover { background: var(--lx-surface-2); color: var(--lx-text); text-decoration: none; }
.lx-nav-a--on  { background: var(--lx-primary-soft); color: var(--lx-primary); font-weight: var(--lx-fw-bold); }
.lx-nav-a--on::after {
  content: '';
  position: absolute;
  inset-inline: var(--lx-sp-3);
  inset-block-end: calc(var(--lx-sp-2) * -1);
  block-size: var(--lx-bw-accent);
  border-radius: var(--lx-r-pill);
  background: var(--lx-primary);
}

.lx-top-side {
  display: flex; align-items: center; gap: var(--lx-sp-2);
  margin-inline-start: auto; flex: none;
}

/* Headline chips. Hidden below the sm tier: on a narrow phone they push the
   account menu off the bar, and every number they show is on the dashboard
   anyway. */
.lx-top-side .lx-chip { padding-inline: var(--lx-sp-2); gap: var(--lx-sp-1); }
.lx-chip--streak { color: var(--lx-streak); border-color: transparent; background: var(--lx-warn-soft); }
.lx-chip--xp     { color: var(--lx-warn-text); border-color: transparent; background: var(--lx-warn-soft); }
.lx-chip--due    { color: var(--lx-info-text); border-color: transparent; background: var(--lx-info-soft); }
a.lx-chip--due:hover { color: var(--lx-info-text); border-color: var(--lx-info-border); }
.lx-num-b { font-variant-numeric: tabular-nums; font-weight: 800; }

@media (max-width: 640px) {
  .lx-chip--streak, .lx-chip--xp { display: none; }
}

/* The daily-goal sliver under the bar. Deliberately thin and unlabelled: it is
   ambient, and a labelled progress bar in the chrome competes with the one on
   the dashboard that actually explains itself. */
.lx-top-goal { border-radius: 0; block-size: var(--lx-bw-accent); background: transparent; }
.lx-top-goal > i { --_c: var(--lx-ok); }


/* ── Theme toggle ───────────────────────────────────────────────
   The glyph is drawn in CSS rather than swapped in JS, so it is correct on
   first paint even before lx-theme.js loads. */

.lx-theme-ico {
  display: inline-block; inline-size: 18px; block-size: 18px;
  border-radius: 50%;
  border: var(--lx-bw-thick) solid currentColor;
  background: linear-gradient(to inline-end, currentColor 0 50%, transparent 50% 100%);
}


/* ── Account menu ───────────────────────────────────────────────
   <details> rather than a JS dropdown: it opens, closes, traps nothing it
   should not, and works before any script has run. */

.lx-menu { position: relative; }
.lx-menu > summary { list-style: none; cursor: pointer; }
.lx-menu > summary::-webkit-details-marker { display: none; }

.lx-menu-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-inline-size: 36px; min-block-size: 36px;
  border-radius: var(--lx-r-pill);
}
.lx-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  inline-size: 32px; block-size: 32px;
  border-radius: 50%;
  background: var(--lx-primary-soft); color: var(--lx-primary);
  font-weight: 800; font-size: var(--lx-fs-sm);
  text-transform: uppercase;
}

.lx-menu-pop {
  position: absolute;
  inset-block-start: calc(100% + var(--lx-sp-2));
  inset-inline-end: 0;
  z-index: var(--lx-z-overlay);
  min-inline-size: 220px;
  padding: var(--lx-sp-2);
  border: var(--lx-bw-hair) solid var(--lx-border);
  border-radius: var(--lx-r-lg);
  background: var(--lx-surface);
  box-shadow: var(--lx-shadow-lg);
}
.lx-menu-head {
  display: grid; gap: 2px;
  padding: var(--lx-sp-2) var(--lx-sp-3) var(--lx-sp-3);
  border-block-end: var(--lx-bw-hair) solid var(--lx-border);
  margin-block-end: var(--lx-sp-2);
}
.lx-menu-a {
  display: block; width: 100%;
  padding: var(--lx-sp-2) var(--lx-sp-3);
  border-radius: var(--lx-r-sm);
  color: var(--lx-text-2); font-size: var(--lx-fs-sm); font-weight: 600;
  text-align: start; text-decoration: none;
}
.lx-menu-a:hover { background: var(--lx-surface-2); color: var(--lx-text); text-decoration: none; }
.lx-menu-a--btn { border: 0; background: none; cursor: pointer; font-family: inherit; }
.lx-menu-form { margin: 0; }


/* ── Phone tab bar ──────────────────────────────────────────────
   Fixed, unlike the top bar, because it must stay reachable by a thumb while
   the page scrolls. The safe-area inset keeps it above the home indicator. */

.lx-tabbar { display: none; }

@media (max-width: 900px) {
  .lx-tabbar {
    position: fixed;
    inset-inline: 0;
    inset-block-end: 0;
    z-index: var(--lx-z-sticky);
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    background: var(--lx-surface);
    border-block-start: var(--lx-bw-hair) solid var(--lx-border);
    padding-block-end: env(safe-area-inset-bottom, 0px);
  }
  .lx-tabbar-a {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 2px;
    min-block-size: 60px;
    color: var(--lx-text-3);
    font-size: var(--lx-fs-xs); font-weight: 600;
    text-decoration: none;
  }
  .lx-tabbar-a:hover { text-decoration: none; color: var(--lx-text-2); }
  .lx-tabbar-a--on { color: var(--lx-primary); }
  .lx-tabbar-ico { display: block; line-height: 0; }
}


/* ── Footer ─────────────────────────────────────────────────── */

.lx-foot {
  margin-block-start: var(--lx-sp-7);
  padding-block: var(--lx-sp-5);
  border-block-start: var(--lx-bw-hair) solid var(--lx-border);
  color: var(--lx-text-3);
  font-size: var(--lx-fs-sm);
}
.lx-foot-in { display: flex; align-items: center; gap: var(--lx-sp-2); flex-wrap: wrap; }
.lx-foot a { color: var(--lx-text-3); }
.lx-foot a:hover { color: var(--lx-text-2); }
/* .lx-foot-sep moved to base.css — the admin footer emits it too. */


/* Section headers, the progress ring and the stat tile used to live here.
   They moved to base.css — see the "Page furniture" note there. Both shells
   emit them, and an admin page never loads this file. */


/* ── Auth screens ───────────────────────────────────────────── */

.lx-auth {
  max-inline-size: var(--lx-w-narrow);
  margin-inline: auto;
  padding-block: var(--lx-sp-7);
  padding-inline: var(--lx-sp-4);
}
.lx-auth-head { text-align: center; margin-block-end: var(--lx-sp-5); }
.lx-auth-head h1 { font-size: var(--lx-fs-2xl); }
.lx-auth-alt { text-align: center; margin-block-start: var(--lx-sp-4); font-size: var(--lx-fs-sm); color: var(--lx-text-2); }


/* ── Landing ────────────────────────────────────────────────── */

.lx-hero { padding-block: var(--lx-sp-8) var(--lx-sp-7); text-align: center; }
/* The one place the type scale is allowed to be fluid. The clamp ceiling is
   --lx-fs-4xl, which exists so this line stops being the only size in the
   project that was invented at its call site. */
.lx-hero h1 {
  font-size: clamp(var(--lx-fs-2xl), 5vw, var(--lx-fs-4xl));
  max-inline-size: 22ch; margin-inline: auto;
}
.lx-hero p { max-inline-size: 56ch; margin-inline: auto; color: var(--lx-text-2); font-size: var(--lx-fs-lg); }
.lx-hero-acts { display: flex; gap: var(--lx-sp-3); justify-content: center; flex-wrap: wrap; margin-block-start: var(--lx-sp-5); }

.lx-feat { display: grid; gap: var(--lx-sp-3); }
.lx-feat-ico {
  display: inline-flex; align-items: center; justify-content: center;
  inline-size: 40px; block-size: 40px;
  border-radius: var(--lx-r-md);
  background: var(--lx-primary-soft); color: var(--lx-primary);
}


/* ── Continue card ───────────────────────────────────────────────
   The single most important element on the dashboard, and sized like it. */

.lx-continue {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--lx-sp-4); flex-wrap: wrap;
  padding: var(--lx-sp-5);
  border-radius: var(--lx-r-xl);
  background: linear-gradient(135deg, var(--lx-ink-600), var(--lx-ink-800));
  color: var(--lx-on-brand);
  text-decoration: none;
  box-shadow: var(--lx-shadow-md);
  margin-block-end: var(--lx-sp-5);
  transition: transform var(--lx-t-fast) var(--lx-ease), box-shadow var(--lx-t-fast) var(--lx-ease);
}
.lx-continue:hover { transform: translateY(-2px); box-shadow: var(--lx-shadow-lg); text-decoration: none; color: var(--lx-on-brand); }
.lx-continue h2 { margin: var(--lx-sp-1) 0; color: inherit; font-size: var(--lx-fs-xl); }
.lx-continue .lx-caps { color: var(--lx-on-brand-dim); }
.lx-continue .lx-muted { color: var(--lx-on-brand-dim); }
/* The gradient is ink in both themes, so the button on it is fixed too —
   same reasoning as --lx-on-brand. */
.lx-continue .lx-btn { background: var(--lx-parch-0); color: var(--lx-ink-700); flex: none; }
.lx-continue .lx-btn:hover { background: var(--lx-parch-0); color: var(--lx-ink-800); }


/* ── Today ─────────────────────────────────────────────────────── */

.lx-today { display: grid; gap: var(--lx-sp-4); margin-block-end: var(--lx-sp-5); }
@media (min-width: 900px) { .lx-today { grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); } }

.lx-today-goal { display: flex; align-items: center; gap: var(--lx-sp-4); }
.lx-today-goal h3 { margin-block-end: var(--lx-sp-1); }


/* ── Skill rows ────────────────────────────────────────────────── */

.lx-skills { display: grid; gap: var(--lx-sp-4); }
.lx-skill-row .lx-help { margin-block-start: var(--lx-sp-1); }


/* ── Weakness cards ────────────────────────────────────────────── */

.lx-weak { display: grid; gap: var(--lx-sp-2); }
.lx-chip--ok { background: var(--lx-ok-soft); color: var(--lx-ok-text); border-color: transparent; }
.lx-chip--sm { min-height: 28px; padding: 0 var(--lx-sp-2); font-size: var(--lx-fs-xs); }


/* The activity heat strip moved to base.css with the rest of the page
   furniture — the admin dashboard draws it too. */


/* ── Level groups on the browse screens ──────────────────────────────
   grammar / reading / writing / listening / speaking / conversation all
   used to list every level at once, sorted by band and otherwise
   undifferentiated — an A1 learner met A0 beside B1 and was left to pick.

   The current band renders open; revision, the next level and anything the
   placement test skipped collapse into these. Collapsed, never removed:
   locking is deliberately soft here (see inc/lx/content.php), so the whole
   library stays one click away and ?all=1 flattens it entirely. */

.lx-lvgrp {
  margin-block-start: var(--lx-sp-5);
  border-block-start: 1px solid var(--lx-border);
  padding-block-start: var(--lx-sp-3);
}

.lx-lvgrp > summary {
  cursor: pointer;
  list-style: none;
  display: flex; align-items: center; gap: var(--lx-sp-2);
  font-weight: 700;
  color: var(--lx-text-2);
}

.lx-lvgrp > summary::-webkit-details-marker { display: none; }

.lx-lvgrp > summary::after {
  content: '';
  inline-size: 0; block-size: 0;
  border-inline-start: 5px solid currentColor;
  border-block: 5px solid transparent;
  transition: transform 150ms ease;
}

/* The marker points along the reading direction, so it has to flip in RTL
   rather than being drawn once and rotated by 180deg on one side only. */
[dir="rtl"] .lx-lvgrp > summary::after { transform: scaleX(-1); }
.lx-lvgrp[open] > summary::after { transform: rotate(90deg); }
[dir="rtl"] .lx-lvgrp[open] > summary::after { transform: scaleX(-1) rotate(-90deg); }

.lx-lvgrp > summary:hover { color: var(--lx-text); }

.lx-lvgrp-body { margin-block-start: var(--lx-sp-3); }

.lx-lvgrp-hint {
  margin-block-start: var(--lx-sp-1);
  font-size: var(--lx-fs-sm);
  color: var(--lx-text-3);
}
