/* ============================================================
   Pathway GED — application shell

   The furniture that surrounds every page: the top bar and its account
   controls, menus, the search palette, the footer, and the shared
   loading and empty states.

   Everything references tokens.css. No raw hex.
   ============================================================ */

/* ============================================================
   1. TOP BAR

   One centred grid shared with the page content: the logo sits on the
   same left edge as the hero, and the account control on the same right
   edge as the course cards. The bar keeps its original height — the
   account additions fit inside it rather than growing it.
   ============================================================ */
.topbar {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(14px) saturate(1.3);
  border-bottom: 1px solid var(--line);
}
.topbar__inner {
  max-width: var(--container); margin: 0 auto; padding: var(--sp-3) var(--sp-5);
  display: flex; align-items: center; gap: var(--sp-4);
  min-height: 62px;
}

.brand {
  font-family: var(--font-display); font-weight: 800; font-size: var(--text-lg);
  color: var(--ink); display: flex; align-items: center; gap: var(--sp-2);
  flex: none; border-radius: var(--r-sm);
}
.brand:hover { text-decoration: none; }
.brand__mark {
  width: 30px; height: 30px; border-radius: 9px; background: var(--brand);
  color: var(--on-brand); display: grid; place-items: center;
  font-size: var(--text-xs); font-weight: 800; letter-spacing: 0;
}

/* ---------- primary links ---------- */
.topbar__nav {
  display: flex; gap: 2px; margin-left: auto; align-items: center;
  min-width: 0;
}
.topbar__link {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  height: var(--h-xs); padding: 0 var(--sp-3);
  color: var(--ink-soft); border-radius: var(--r-full);
  font-size: var(--text-sm); font-weight: 600; white-space: nowrap;
  background: none; border: none; font-family: var(--font-text); cursor: pointer;
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.topbar__link:hover { background: var(--surface-2); text-decoration: none; color: var(--ink); }
.topbar__link[aria-current="page"] { background: var(--brand-tint); color: var(--brand-strong); }

/* The ⌘K badge on the search control. Hidden where there is no keyboard
   worth advertising. */
.kbd {
  font-family: var(--font-mono); font-size: 0.6875rem; font-weight: 600;
  color: var(--ink-faint); border: 1px solid var(--line);
  background: var(--surface-2); border-radius: var(--r-xs);
  padding: 1px 5px; line-height: 1.4;
}
@media (max-width: 1000px) { .topbar__link .kbd { display: none; } }

/* ---------- the right-hand cluster ----------
   XP · Upgrade · bell · avatar, on one row, vertically centred against
   the logo and the links. Everything here is flex so a control added or
   removed never wraps and never changes the header's height. */
.topbar__end {
  display: flex; align-items: center; gap: var(--sp-2);
  flex: none; margin-left: var(--sp-3);
}
.topbar__tools {
  display: flex; align-items: center; gap: var(--sp-2); flex: none;
}
.topbar__tools:empty { display: none; }
.topbar__divider {
  width: 1px; height: 20px; background: var(--line); flex: none;
  margin: 0 var(--sp-1);
}

/* Daily-goal pill. A button, because it opens the goal panel — but it
   reads as a status chip, which is what keeps the gamification adult. */
.xp-pill {
  display: inline-flex; align-items: center; gap: 7px;
  height: var(--h-xs); padding: 0 12px;
  font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 600;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-full); color: var(--ink-soft);
  cursor: pointer; white-space: nowrap;
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.xp-pill:hover { color: var(--ink); border-color: var(--line-strong); }
.xp-pill__bolt { color: var(--brand); flex: none; display: grid; place-items: center; }
.xp-pill__bolt svg { width: 13px; height: 13px; }
.xp-pill.is-met .xp-pill__bolt { color: var(--good); }
.xp-pill__streak { color: var(--ink-faint); }

/* Icon-only controls (the notification bell, the mobile menu). */
.icon-btn {
  display: inline-grid; place-items: center; position: relative;
  width: var(--h-xs); height: var(--h-xs); flex: none;
  border-radius: var(--r-full); border: 1px solid transparent;
  background: none; color: var(--ink-soft); cursor: pointer;
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.icon-btn:hover { background: var(--surface-2); color: var(--ink); }
.icon-btn[aria-expanded="true"] { background: var(--surface-2); color: var(--ink); }
.icon-btn svg { width: 17px; height: 17px; }
/* A dot, never a fabricated count — it appears only when there is a real
   item waiting. */
.icon-btn__dot {
  position: absolute; top: 4px; right: 5px; width: 7px; height: 7px;
  border-radius: 50%; background: var(--brand);
  box-shadow: 0 0 0 2px var(--paper);
}

/* ---------- account button ---------- */
.account-btn {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  height: var(--h-sm); padding: 0 10px 0 3px;
  border-radius: var(--r-full);
  border: 1px solid var(--line); background: var(--surface-2);
  color: var(--ink); font-size: var(--text-sm); font-weight: 600;
  font-family: var(--font-text); cursor: pointer; text-decoration: none;
  max-width: 200px;
  transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.account-btn:hover { background: var(--line); border-color: var(--line-strong); text-decoration: none; }
.account-btn[aria-expanded="true"] { background: var(--line); border-color: var(--line-strong); }
.avatar {
  flex: none; width: 30px; height: 30px; border-radius: 50%;
  background: var(--brand); color: var(--on-brand);
  display: grid; place-items: center; overflow: hidden;
  font-family: var(--font-display); font-weight: 800; font-size: var(--text-sm);
  line-height: 1; user-select: none;
}
.avatar img { width: 100%; height: 100%; object-fit: cover; }
.avatar--lg { width: 56px; height: 56px; font-size: var(--text-xl); }
.account-btn__label {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.account-btn__caret { flex: none; color: var(--ink-faint); }
.account-btn__caret svg { width: 12px; height: 12px; }

.topbar__account { display: flex; align-items: center; gap: var(--sp-2); }

/* ---------- auth loading ----------
   The bar reserves the exact space the resolved control will occupy, so
   nothing on the page moves when Firebase reports in. */
.auth-skeleton { display: flex; align-items: center; gap: var(--sp-2); }

/* ============================================================
   2. MENUS (account, notifications, daily goal)
   ============================================================ */
/* Menus are appended to <body> and given viewport coordinates by
   js/ui/menu.js — see the note there about backdrop-filter creating a
   containing block. */
.menu {
  position: fixed; z-index: 70;
  min-width: 244px; max-width: min(360px, calc(100vw - var(--sp-8)));
  max-height: calc(100vh - 96px); overflow-y: auto;
  padding: var(--sp-2);
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--r-md); box-shadow: var(--shadow-menu);
  transform-origin: top right;
  animation: menu-in var(--t-med) var(--ease);
}
@keyframes menu-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) { .menu { animation: none; } }

.menu-anchor { position: relative; }

.menu__head {
  padding: var(--sp-3) var(--sp-3) var(--sp-3);
  display: flex; gap: var(--sp-3); align-items: center;
}
.menu__identity { min-width: 0; flex: 1; }
.menu__name, .menu__email {
  display: block; margin: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.menu__name {
  font-family: var(--font-display); font-weight: 700; font-size: var(--text-sm);
  color: var(--ink); line-height: 1.3;
}
.menu__email {
  font-size: var(--text-xs); color: var(--ink-faint); line-height: 1.4;
}
.menu__sep { height: 1px; background: var(--hairline); margin: var(--sp-2) 0; border: none; }

.menu__item {
  display: flex; align-items: center; gap: var(--sp-3); width: 100%;
  padding: 9px var(--sp-3); border-radius: var(--r-sm);
  font-size: var(--text-sm); font-weight: 600; color: var(--ink-soft);
  background: none; border: none; font-family: var(--font-text);
  text-align: left; cursor: pointer; text-decoration: none;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.menu__item:hover, .menu__item:focus-visible {
  background: var(--surface-2); color: var(--ink); text-decoration: none;
}
.menu__item svg { width: 16px; height: 16px; flex: none; opacity: .8; }
.menu__item .menu__trail { margin-left: auto; font-size: var(--text-xs); color: var(--ink-faint); font-weight: 600; }
.menu__item--danger { color: var(--ink-soft); }
.menu__item--danger:hover { background: var(--bad-tint); color: var(--bad); }

.menu__title {
  font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .08em; color: var(--ink-faint);
  padding: var(--sp-2) var(--sp-3) var(--sp-1); margin: 0;
}
.menu__note {
  padding: var(--sp-2) var(--sp-3) var(--sp-3);
  font-size: var(--text-sm); color: var(--ink-soft); margin: 0;
}

/* ---------- notifications ---------- */
.menu--notes { min-width: 300px; max-width: 340px; }
.note-item { align-items: flex-start; padding: var(--sp-3); }
.note-item__body { min-width: 0; }
.note-item__title { display: block; color: var(--ink); font-size: var(--text-sm); }
.note-item__text { display: block; font-weight: 400; font-size: var(--text-xs); color: var(--ink-faint); line-height: 1.5; }
.note-item__mark {
  flex: none; width: 8px; height: 8px; border-radius: 50%; margin-top: 6px;
  background: var(--brand);
}
.note-item__mark--warn { background: var(--warn); }
.menu__empty {
  padding: var(--sp-5) var(--sp-4); text-align: center;
}
.menu__empty p { margin: 0; font-size: var(--text-sm); color: var(--ink-soft); }
.menu__empty .tiny { margin-top: 4px; }

/* ---------- daily goal ---------- */
.menu--goal { min-width: 268px; }
.goal-panel { padding: var(--sp-3); }
.goal-panel__row { display: flex; align-items: center; gap: var(--sp-4); }
.goal-panel__value {
  font-family: var(--font-mono); font-weight: 700; font-size: var(--text-xl); color: var(--ink);
  line-height: 1;
}
.goal-panel__value span { color: var(--ink-faint); font-size: var(--text-md); }
.goal-panel .meter { margin-top: var(--sp-3); }
.goal-panel p { font-size: var(--text-sm); color: var(--ink-soft); margin: var(--sp-3) 0 0; }

/* ============================================================
   3. MOBILE

   Phones keep the bottom tab bar for the primary destinations — it is
   the faster pattern for a study app — and the account button opens the
   same menu as a bottom sheet. There is deliberately no second, competing
   hamburger navigation.
   ============================================================ */
.tabbar { display: none; }

@media (max-width: 860px) {
  .topbar__nav { display: none; }
  .topbar__end { margin-left: auto; }

  .tabbar {
    display: flex; position: fixed; bottom: 0; left: 0; right: 0; z-index: 60;
    background: color-mix(in srgb, var(--surface) 92%, transparent);
    backdrop-filter: blur(14px) saturate(1.3);
    border-top: 1px solid var(--line);
    padding: var(--sp-1) var(--sp-2) calc(var(--sp-1) + env(safe-area-inset-bottom));
  }
  .tabbar a {
    flex: 1; text-align: center; padding: var(--sp-2) 0; color: var(--ink-faint);
    font-size: 0.6875rem; font-weight: 700; border-radius: var(--r-sm);
    display: flex; flex-direction: column; align-items: center; gap: 2px;
    transition: color var(--t-fast) var(--ease);
  }
  .tabbar a svg { width: 22px; height: 22px; }
  .tabbar a[aria-current="page"] { color: var(--brand); }
  .tabbar a:hover { text-decoration: none; color: var(--ink-soft); }
  main { padding-bottom: 96px; }

  /* Name and caret drop away before the avatar does, so the control
     never squeezes the logo. */
  .account-btn__label, .account-btn__caret { display: none; }
  .account-btn { padding: 0; border-color: transparent; background: none; }
  .xp-pill__streak { display: none; }
}

@media (max-width: 560px) {
  .topbar__inner { gap: var(--sp-2); padding-inline: var(--sp-4); }
  /* The goal pill has a home on the Today page and in the tab bar; the
     wordmark does not, so it is the last thing to go. */
  .xp-pill { display: none; }
  .topbar__divider { display: none; }
  .topbar__account .btn { padding: 0 14px; }
}
@media (max-width: 359px) {
  .brand span:not(.brand__mark) { display: none; }
}

/* The menu becomes a bottom sheet on a phone: reachable by thumb, and
   wide enough that the email address is not truncated to nothing. */
@media (max-width: 560px) {
  .menu {
    inset: auto 0 0 0;
    min-width: 0; width: 100%; max-width: none;
    max-height: 80vh;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    border-left: none; border-right: none; border-bottom: none;
    padding: var(--sp-3) var(--sp-3) calc(var(--sp-4) + env(safe-area-inset-bottom));
    animation: sheet-in var(--t-med) var(--ease);
  }
  @keyframes sheet-in {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: translateY(0); }
  }
  .menu__item { padding: 12px var(--sp-3); }
  .menu-scrim {
    position: fixed; inset: 0; z-index: 69;
    background: color-mix(in srgb, var(--ink) 34%, transparent);
  }
}
.menu-scrim { display: none; }
@media (max-width: 560px) { .menu-scrim { display: block; } }

/* ============================================================
   4. SEARCH PALETTE  (⌘K / Ctrl K)
   ============================================================ */
.palette-scrim {
  position: fixed; inset: 0; z-index: 100;
  background: color-mix(in srgb, var(--ink) 40%, transparent);
  backdrop-filter: blur(3px);
  display: flex; justify-content: center; align-items: flex-start;
  padding: var(--sp-10) var(--sp-4) var(--sp-4);
  animation: fade-in var(--t-fast) var(--ease);
}
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

.palette {
  width: 100%; max-width: 620px; max-height: min(70vh, 560px);
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--r-md); box-shadow: var(--shadow-menu);
  animation: menu-in var(--t-med) var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  .palette, .palette-scrim { animation: none; }
}
.palette__bar {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5); border-bottom: 1px solid var(--hairline);
  flex: none;
}
.palette__bar svg { width: 18px; height: 18px; color: var(--ink-faint); flex: none; }
.palette__input {
  flex: 1; min-width: 0; font: inherit; font-size: var(--text-md);
  background: none; border: none; color: var(--ink); padding: 0;
}
.palette__input:focus { outline: none; }
.palette__input::placeholder { color: var(--ink-faint); }
.palette__input:focus-visible { box-shadow: none; }

.palette__results { overflow-y: auto; padding: var(--sp-2); flex: 1; }
.palette__group {
  font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .08em; color: var(--ink-faint);
  padding: var(--sp-3) var(--sp-3) var(--sp-1); margin: 0;
}
.palette__item {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 10px var(--sp-3); border-radius: var(--r-sm);
  color: var(--ink); text-decoration: none; cursor: pointer;
  transition: background var(--t-fast) var(--ease);
}
.palette__item:hover, .palette__item.is-active { background: var(--surface-2); text-decoration: none; }
.palette__item.is-active { box-shadow: inset 2px 0 0 var(--accent, var(--brand)); }
.palette__dot {
  flex: none; width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent, var(--ink-faint));
}
.palette__body { min-width: 0; flex: 1; }
.palette__title {
  display: block; font-size: var(--text-sm); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.palette__sub {
  display: block; font-size: var(--text-xs); color: var(--ink-faint);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.palette__lock { flex: none; color: var(--ink-faint); display: inline-flex; }
.palette__lock svg { width: 14px; height: 14px; }
.palette__foot {
  display: flex; gap: var(--sp-4); align-items: center; flex: none;
  padding: var(--sp-3) var(--sp-5); border-top: 1px solid var(--hairline);
  font-size: var(--text-xs); color: var(--ink-faint);
}
.palette__foot span { display: inline-flex; align-items: center; gap: 6px; }
@media (max-width: 560px) {
  .palette-scrim { padding: var(--sp-4) var(--sp-3); }
  .palette__foot { display: none; }
}

/* ============================================================
   5. LOADING SKELETONS

   Shaped like the content they stand in for, so the layout does not jump
   when real data lands. No spinners at page scale.
   ============================================================ */
.sk {
  display: block; border-radius: var(--r-xs);
  background: var(--skeleton);
  position: relative; overflow: hidden;
}
.sk::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, var(--skeleton-sheen), transparent);
  transform: translateX(-100%);
  animation: sk-sweep 1.5s var(--ease) infinite;
}
@media (prefers-reduced-motion: reduce) { .sk::after { animation: none; } }
@keyframes sk-sweep { to { transform: translateX(100%); } }

.sk--text { height: 0.9em; margin: 0.28em 0; border-radius: var(--r-xs); }
.sk--pill { height: var(--h-xs); border-radius: var(--r-full); }
.sk--btn { height: var(--h-sm); width: 84px; border-radius: var(--r-full); }
.sk--avatar { width: 30px; height: 30px; border-radius: 50%; }
.sk--card { height: 250px; border-radius: var(--r-lg); }
.sk--panel { height: 132px; border-radius: var(--r-md); }
.sk--row { height: 56px; border-radius: var(--r-sm); }
.sk-stack { display: flex; flex-direction: column; gap: var(--sp-4); }

/* ============================================================
   6. EMPTY STATES
   ============================================================ */
.empty {
  text-align: center; padding: var(--sp-12) var(--sp-6);
  border: 1px dashed var(--line-strong); border-radius: var(--r-lg);
  background: var(--surface);
}
.empty__icon {
  width: 46px; height: 46px; margin: 0 auto var(--sp-4);
  display: grid; place-items: center; border-radius: var(--r-sm);
  background: var(--surface-2); color: var(--ink-faint);
}
.empty__icon svg { width: 22px; height: 22px; }
.empty h3 { margin: 0 0 var(--sp-2); font-size: var(--text-lg); }
.empty p { margin: 0 auto; max-width: 44ch; color: var(--ink-soft); font-size: var(--text-sm); }
.empty .q__actions { justify-content: center; margin-top: var(--sp-5); }

/* ============================================================
   7. HOME — hero actions, welcome line, continue card
   ============================================================ */
/* Sentence case, not the uppercase mono kicker used elsewhere: this line
   is a greeting, and a greeting in capitals reads as shouting. */
.hero__welcome {
  font-family: var(--font-text); font-size: var(--text-md); font-weight: 600;
  color: var(--brand); display: block; margin-bottom: var(--sp-2);
}
.hero__actions {
  display: flex; align-items: center; gap: var(--sp-3);
  margin-top: var(--sp-6); flex-wrap: wrap;
}

.continue-card {
  display: grid; grid-template-columns: 1fr auto; gap: var(--sp-5);
  align-items: center; padding: var(--sp-5) var(--sp-6);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-1);
  position: relative; overflow: hidden;
}
.continue-card::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 4px;
  background: var(--accent, var(--brand));
}
.continue-card__meta {
  font-family: var(--font-mono); font-size: var(--text-xs); color: var(--ink-faint);
  display: block; margin-bottom: 6px;
}
.continue-card h3 { margin: 0 0 var(--sp-1); font-size: var(--text-lg); }
.continue-card p { margin: 0; font-size: var(--text-sm); color: var(--ink-soft); }
.continue-card .meter { margin-top: var(--sp-3); max-width: 300px; }
@media (max-width: 640px) {
  .continue-card { grid-template-columns: 1fr; }
  .continue-card .btn { width: 100%; }
}

/* Course-card footer line: "Continue: Place Value →" */
.subject-card .continue { display: inline-flex; align-items: center; gap: 6px; }

/* ============================================================
   8. TODAY'S STUDY dashboard
   ============================================================ */
/* The goal spans the row; the two things you can actually do sit beneath
   it, side by side. Three equal cards would give the goal the same weight
   as an action, which it does not have. */
.today-grid {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: var(--sp-4); margin: var(--sp-5) 0;
}
.today-card--wide { grid-column: 1 / -1; }
@media (max-width: 640px) { .today-grid { grid-template-columns: 1fr; } }
.today-card {
  padding: var(--sp-5); display: flex; flex-direction: column; gap: var(--sp-2);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); box-shadow: var(--shadow-1);
}
.today-card__tag {
  font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .08em; color: var(--ink-faint);
}
.today-card h4 { margin: 0; }
.today-card p { margin: 0; font-size: var(--text-sm); color: var(--ink-soft); }
.today-card .btn { margin-top: auto; align-self: flex-start; }
.today-goal { display: flex; align-items: baseline; gap: var(--sp-4); flex-wrap: wrap; }
.today-goal__figures { min-width: 0; flex: none; }
.today-goal p { flex: 1; min-width: 180px; }
.today-card--wide .meter { margin-top: var(--sp-2); }
.today-goal__value {
  font-family: var(--font-mono); font-weight: 700; font-size: var(--text-2xl);
  line-height: 1; color: var(--ink);
}
.today-goal__value span { color: var(--ink-faint); font-size: var(--text-lg); }

/* ============================================================
   9. ACCOUNT — settings layout
   ============================================================ */
.settings {
  display: grid; grid-template-columns: 208px 1fr; gap: var(--sp-8);
  align-items: start; margin: var(--sp-6) 0;
}
@media (max-width: 820px) { .settings { grid-template-columns: 1fr; gap: var(--sp-5); } }

.settings__nav {
  display: flex; flex-direction: column; gap: 2px;
  position: sticky; top: 84px;
}
@media (max-width: 820px) {
  .settings__nav {
    position: static; flex-direction: row; gap: var(--sp-1);
    overflow-x: auto; padding-bottom: var(--sp-2);
    border-bottom: 1px solid var(--line);
    scrollbar-width: none;
  }
  .settings__nav::-webkit-scrollbar { display: none; }
}
.settings__link {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 9px var(--sp-3); border-radius: var(--r-sm);
  font-size: var(--text-sm); font-weight: 600; color: var(--ink-soft);
  white-space: nowrap;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.settings__link:hover { background: var(--surface-2); color: var(--ink); text-decoration: none; }
.settings__link[aria-current="page"] { background: var(--brand-tint); color: var(--brand-strong); }
.settings__link svg { width: 16px; height: 16px; flex: none; opacity: .85; }

.settings__body { min-width: 0; display: flex; flex-direction: column; gap: var(--sp-5); }

.panel {
  padding: var(--sp-6); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-md); box-shadow: var(--shadow-1);
}
.panel__head { display: flex; align-items: flex-start; gap: var(--sp-4); margin-bottom: var(--sp-5); }
.panel__head h3 { margin: 0; font-size: var(--text-lg); }
.panel__head p { margin: 4px 0 0; font-size: var(--text-sm); color: var(--ink-soft); }
.panel__head .btn, .panel__head .status-tag { margin-left: auto; flex: none; }
.panel + .panel { margin-top: 0; }
.panel__foot { margin-top: var(--sp-5); display: flex; gap: var(--sp-2); flex-wrap: wrap; }

.profile-row { display: flex; align-items: center; gap: var(--sp-5); margin-bottom: var(--sp-5); }

/* Membership status — a quiet dot and a word, not a banner. */
.status-tag {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: var(--text-xs); font-weight: 700;
  color: var(--ink-soft); border: 1px solid var(--line);
  background: var(--surface-2); border-radius: var(--r-full); padding: 3px 11px;
}
.status-tag__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ink-faint); }
.status-tag--active { color: var(--good); border-color: color-mix(in srgb, var(--good) 32%, transparent); background: var(--good-tint); }
.status-tag--active .status-tag__dot { background: var(--good); }
.status-tag--warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 32%, transparent); background: var(--warn-tint); }
.status-tag--warn .status-tag__dot { background: var(--warn); }

.progress-stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: var(--sp-4); margin-bottom: var(--sp-5);
}
.stat { }
.stat__value { font-family: var(--font-mono); font-weight: 700; font-size: var(--text-xl); line-height: 1.1; }
.stat__label { font-size: var(--text-xs); color: var(--ink-faint); }

.subject-progress { display: flex; flex-direction: column; gap: var(--sp-4); }
.subject-progress__row { display: flex; align-items: center; gap: var(--sp-4); font-size: var(--text-sm); }
.subject-progress__row .name { width: 200px; flex: none; font-weight: 600; line-height: 1.35; }
.subject-progress__row .meter { flex: 1; min-width: 60px; }
.subject-progress__row .pct { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--ink-faint); width: 40px; text-align: right; }
@media (max-width: 560px) {
  .subject-progress__row { flex-wrap: wrap; }
  .subject-progress__row .name { width: 100%; }
}

/* Preference choices (daily goal) */
.choice-row { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.choice {
  display: inline-flex; flex-direction: column; gap: 2px; cursor: pointer;
  padding: var(--sp-3) var(--sp-4); border-radius: var(--r-sm);
  border: 1.5px solid var(--line); background: var(--surface);
  font-size: var(--text-sm); font-weight: 600; text-align: left;
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.choice:hover { border-color: var(--line-strong); background: var(--surface-2); }
.choice[aria-pressed="true"] { border-color: var(--brand); background: var(--brand-tint); color: var(--brand-strong); }
.choice .sub { font-size: var(--text-xs); font-weight: 400; color: var(--ink-faint); }
.choice[aria-pressed="true"] .sub { color: inherit; opacity: .8; }

/* ============================================================
   10. FOOTER
   ============================================================ */
.site-footer {
  border-top: 1px solid var(--line);
  margin-top: var(--sp-20);
  padding: var(--sp-12) 0 var(--sp-10);
  background: var(--paper);
}
.site-footer__inner {
  max-width: var(--container); margin: 0 auto; padding: 0 var(--sp-5);
}
.site-footer__top {
  display: grid; grid-template-columns: 1.4fr repeat(3, 1fr); gap: var(--sp-8);
  margin-bottom: var(--sp-10);
}
@media (max-width: 820px) {
  .site-footer__top { grid-template-columns: repeat(2, 1fr); gap: var(--sp-6); }
  .site-footer__brand { grid-column: 1 / -1; }
}
@media (max-width: 480px) { .site-footer__top { grid-template-columns: 1fr; } }

.site-footer__brand .brand { margin-bottom: var(--sp-3); }
.site-footer__brand p {
  font-size: var(--text-sm); color: var(--ink-soft); max-width: 30ch; margin: 0;
}
.site-footer h2 {
  font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .08em; color: var(--ink-faint);
  margin: 0 0 var(--sp-3);
}
.site-footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.site-footer a {
  color: var(--ink-soft); font-size: var(--text-sm); font-weight: 600;
  transition: color var(--t-fast) var(--ease);
}
.site-footer a:hover { color: var(--ink); text-decoration: none; }
.site-footer__legal {
  border-top: 1px solid var(--line); padding-top: var(--sp-5);
  display: flex; gap: var(--sp-5); align-items: flex-start; flex-wrap: wrap;
}
.site-footer__legal p { margin: 0; font-size: var(--text-xs); color: var(--ink-faint); line-height: 1.6; }
.site-footer__disclaimer { max-width: 68ch; }
.site-footer__copy {
  margin-left: auto !important;
  display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap;
}
.site-footer__links { display: inline-flex; gap: var(--sp-4); }
.site-footer__links a { font-size: var(--text-xs); font-weight: 600; }
@media (max-width: 860px) { .site-footer__copy { margin-left: 0 !important; } }
@media (max-width: 860px) { .site-footer { padding-bottom: 110px; } }

/* ============================================================
   11. ACCOUNT PROMPT — shown to signed-out visitors on pages whose
   value depends on having an account. Never a blocker.
   ============================================================ */
.account-prompt {
  display: flex; gap: var(--sp-4); align-items: center; flex-wrap: wrap;
  padding: var(--sp-4) var(--sp-5); margin: var(--sp-5) 0;
  background: var(--brand-tint); border-radius: var(--r-md);
  border: 1px solid color-mix(in srgb, var(--brand) 22%, transparent);
}
.account-prompt__body { flex: 1; min-width: 220px; }
.account-prompt strong { display: block; font-family: var(--font-display); font-size: var(--text-sm); }
.account-prompt p { margin: 2px 0 0; font-size: var(--text-sm); color: var(--ink-soft); }
.account-prompt .q__actions { margin: 0; }

/* ============================================================
   12. LEGAL PAGES  (Privacy Policy, Terms & Conditions)

   Long-form reading, so the measure is narrower than the dashboard and
   the line height is looser. Everything else — surface, borders, accent,
   type — is the same language as the rest of the site.
   ============================================================ */
.container--legal { max-width: 820px; }

.legal-header { margin: var(--sp-8) 0 var(--sp-6); }
.legal-header h1 { font-size: var(--text-2xl); margin-bottom: var(--sp-2); }
.legal-updated {
  font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 600;
  color: var(--ink-faint); margin: 0 0 var(--sp-5);
}
.legal-lead {
  font-size: var(--text-lg); line-height: 1.6; color: var(--ink-soft);
  margin: 0; max-width: 62ch;
}

/* ---------- contents ---------- */
.legal-toc {
  padding: var(--sp-5) var(--sp-6);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); margin-bottom: var(--sp-10);
}
.legal-toc h2 {
  font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .08em; color: var(--ink-faint);
  margin: 0 0 var(--sp-3);
}
.legal-toc ol {
  list-style: none; margin: 0; padding: 0;
  columns: 2; column-gap: var(--sp-8);
}
@media (max-width: 640px) { .legal-toc ol { columns: 1; } }
.legal-toc li { break-inside: avoid; }
.legal-toc a {
  display: flex; gap: var(--sp-3); align-items: baseline;
  padding: 5px 0; color: var(--ink-soft);
  font-size: var(--text-sm); font-weight: 600;
  transition: color var(--t-fast) var(--ease);
}
.legal-toc a:hover { color: var(--brand); text-decoration: none; }
.legal-toc__num {
  font-family: var(--font-mono); font-size: var(--text-xs); color: var(--ink-faint);
  min-width: 1.4em; flex: none;
}

/* ---------- body ---------- */
.legal-body { display: flex; flex-direction: column; gap: var(--sp-10); }

.legal-section {
  /* Clears the sticky top bar when a section is linked to directly. */
  scroll-margin-top: 84px;
}
.legal-section > h2 {
  font-size: var(--text-xl); margin-bottom: var(--sp-4);
  padding-bottom: var(--sp-3); border-bottom: 1px solid var(--line);
  display: flex; gap: var(--sp-3); align-items: baseline;
}
.legal-section__num {
  font-family: var(--font-mono); font-size: var(--text-sm);
  color: var(--brand); font-weight: 600; flex: none;
}
.legal-section p,
.legal-section li { line-height: 1.75; }
.legal-section p { margin: 0 0 var(--sp-4); color: var(--ink-soft); }
.legal-section p:last-child { margin-bottom: 0; }
.legal-section strong { color: var(--ink); }
.legal-section ul {
  margin: 0 0 var(--sp-4); padding: 0; list-style: none;
  display: flex; flex-direction: column; gap: var(--sp-2);
}
.legal-section li {
  position: relative; padding-left: var(--sp-5); color: var(--ink-soft);
}
.legal-section li::before {
  content: ""; position: absolute; left: 4px; top: 0.72em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--line-strong);
}
.legal-section a { text-decoration: underline; text-underline-offset: 2px; }

/* A linked-to section gets a brief, quiet marker so it is obvious which
   one the reader landed on. */
.legal-section.is-target > h2 { border-bottom-color: var(--brand); }

.legal-contact {
  font-family: var(--font-mono); font-size: var(--text-md);
  background: var(--surface-2); border-radius: var(--r-sm);
  padding: var(--sp-4) var(--sp-5); overflow-wrap: anywhere;
}

/* Unresolved business decisions. Deliberately impossible to miss, so
   nothing ships to production as a plausible-looking invention. */
.legal-todo {
  display: inline-block;
  font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 700;
  letter-spacing: .04em;
  background: var(--warn-tint); color: var(--warn);
  border: 1px dashed var(--warn);
  border-radius: var(--r-xs); padding: 3px 9px;
}

/* Small print beside a form or a set of plans. */
.legal-note {
  font-size: var(--text-xs); color: var(--ink-faint); text-align: center;
  margin: var(--sp-4) 0 0;
}
.legal-note a { color: var(--ink-soft); text-decoration: underline; }
.legal-note a:hover { color: var(--ink); }

@media (max-width: 560px) {
  .legal-header h1 { font-size: var(--text-xl); }
  .legal-lead { font-size: var(--text-md); }
  .legal-toc { padding: var(--sp-4) var(--sp-5); }
  .legal-body { gap: var(--sp-8); }
}

/* ============================================================
   13. ERROR / NOT-FOUND pages
   ============================================================ */
.page-state {
  text-align: center; padding: var(--sp-20) var(--sp-5);
  max-width: 46ch; margin: 0 auto;
}
.page-state__code {
  font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint);
}
.page-state h1 { font-size: var(--text-2xl); margin: var(--sp-3) 0 var(--sp-3); }
.page-state p { color: var(--ink-soft); }
.page-state .q__actions { justify-content: center; }
