/* Shared site navigation (rendered by assets/nav.js).
   Desktop: fixed left sidebar + sticky breadcrumb bar. ≤900px: menu panel, section tabs, bottom tab bar. */
:root { --sn-sidebar-width: 248px; --sn-bottom-bar: 66px; --sn-bar: 68px; }

/* No transform/backdrop-filter on the header: the sidebar and bottom bar inside it are position:fixed. */
.site-nav { position:sticky; top:0; z-index:var(--z-nav, 100); margin:0; padding:0; text-align:left; font-family:inherit; }
/* Some pages still carry legacy `header { … }` / `header::after` styles */
.site-nav::before, .site-nav::after { content:none !important; display:none !important; }
.site-nav *, .site-nav *::before, .site-nav *::after { box-sizing:border-box; }
body.has-app-nav { padding-left:var(--sn-sidebar-width); }

.sn-skip { position:fixed; top:8px; left:12px; z-index:var(--z-skip, 150); padding:12px 18px; border-radius: 10px; background: var(--surface); color: var(--ink); transform:translateY(-150%); }
.sn-skip:focus { transform:none; }
/* Sandy Rounded icons (assets/icons.css): 24px in the menu and tab bar, 22px in icon-only buttons, 20px beside menu text */
.sn-icon { display:inline-block; flex-shrink:0; width:24px; height:24px; vertical-align:middle; }
.sn-menu-toggle .sn-icon, .sn-icon-btn .sn-icon { width:22px; height:22px; }
.sn-account-item .sn-icon { width:20px; height:20px; }

/* Sidebar */
/* Menu (2026-10-12, "A + C"): the sidebar and the phone ☰ panel are the page's paper (--surface) with a hairline edge, and no
   logo / slogan block (owner: as simple as possible, no reading burden). Colour lives only in a text-free notepad strip along the
   top (--sn-band-h: 6px on desktop, 20px on the phone panel; a hairline under it) in the palette's quiet partner colour (--color-menu-band / -band-line, assets/appearance.css).
   Hover and current rows use the page's own --tint-1 / --tint-2; the menu colour never goes on text, icons or controls.
   The strip scrolls with the menu (background-attachment: local); --sn-pad-t is the space under it. */
.sn-sidebar { --sn-band-h:6px; --sn-pad-t:22px; --sn-pad-x:18px; position:fixed; inset:0 auto 0 0; z-index:26; display:flex; flex-direction:column; width:var(--sn-sidebar-width); padding:calc(var(--sn-band-h) + 1px + var(--sn-pad-t)) var(--sn-pad-x) 20px; overflow-y:auto; overscroll-behavior:contain; scrollbar-width:thin; border-right: 1px solid var(--border); background: var(--surface); background-image: linear-gradient(var(--color-menu-band, transparent) 0 var(--sn-band-h), var(--color-menu-band-line, transparent) var(--sn-band-h) calc(var(--sn-band-h) + 1px), transparent 0); background-attachment: local; color: var(--ink); box-shadow: var(--shadow-menu, none); }
/* Programmatic focus target when the phone panel opens by touch or mouse (assets/nav.js); keyboard opening focuses the current link */
.sn-sidebar:focus { outline:none; }
.sn-overview { padding-bottom:10px; border-bottom: 1px solid var(--border); }
/* The three study groups (学习 / 练习 / 复习) have no visible labels or numbers (owner, 2026-10-12: no reading burden): one
   hairline between groups is the only separator. The group names stay as aria-labels; the pages keep their own eyebrows. */
.sn-section { margin:10px 0 0; }
.sn-section + .sn-section { margin-top:10px; padding-top:10px; border-top: 1px solid var(--border); }
.sn-side-link { display:flex; align-items:center; gap:12px; min-height:44px; margin:3px 0; padding:10px 13px; border: 1px solid transparent; border-radius: 11px; color: var(--muted); font-size:.86rem; text-decoration:none; }
.sn-side-link:hover { background: var(--tint-1); color: var(--ink); }
.sn-side-link[aria-current="page"] { background: var(--tint-2); color: var(--ink); font-weight:500; }
/* 语法四选一 (unlisted) is reached from 易混辨析: that row says where the learner is, without the page dot */
.sn-side-link[aria-current="location"] { color: var(--ink); font-weight:500; }
/* The current page: one small Sandy-orange dot at the end of the row (colour and weight change too, so it's never the only cue) */
.sn-side-link[aria-current="page"]:not(:has(.sn-count))::after { content:""; flex-shrink:0; width:6px; height:6px; margin-left:auto; border-radius:50%; background: var(--color-accent-deco); }
.sn-side-link:focus-visible, .sn-more-toggle:focus-visible, .sn-menu-toggle:focus-visible, .sn-mobile a:focus-visible, .sn-local a:focus-visible { outline: 2px solid var(--accent-focus); outline-offset:2px; }
.sn-count { min-width:23px; margin-left:auto; padding:2px 7px; border-radius: var(--radius-chip-sm); background: var(--note-cream); color: var(--ink-2); font-size:.7rem; text-align:center; font-variant-numeric:tabular-nums; }
/* 「更多」: one quiet 44px disclosure row at the bottom of the menu with the shared +/− circle (assets/site.css .disclosure),
   folding 联系我 / 关于 Sandy / 支持 Sandy / 分享给朋友 / 隐私政策. It opens by itself on those pages (assets/nav.js), and its label
   turns ink + 500 there so the learner can see where the current page lives. */
.sn-more { margin-top:auto; padding-top:10px; border-top: 1px solid var(--border); }
.sn-more-toggle { display:flex; align-items:center; min-height:44px; padding:0 13px; border-radius: 11px; color: var(--muted); font-size:.8rem; cursor:pointer; user-select:none; }
.sn-more-toggle:hover { background: var(--tint-1); color: var(--ink); }
.sn-more:has([aria-current="page"]) > .sn-more-toggle { color: var(--ink); font-weight:500; }
.sn-more-links { padding-top:2px; }
.sn-more-links .sn-side-link { padding:9px 13px; font-size:.8rem; }
/* 分享给朋友 is an action, so a button that looks like its sibling links (hover from .sn-side-link:hover still wins) */
button.sn-side-link { box-sizing:border-box; width:100%; background:transparent; font:inherit; text-align:left; cursor:pointer; }

/* Top bar */
/* position + z-index: the account menu opens over the page tabs row below (its mask creates a layer that drew on top) */
.sn-topbar { position:relative; z-index:3; display:flex; align-items:center; justify-content:space-between; gap:16px; min-height:calc(var(--sn-bar) + 1px); padding:12px 28px; border-bottom: 1px solid var(--border); background: var(--study-background, var(--page-1)); }
.sn-crumbs { display:flex; align-items:center; gap:11px; min-width:0; font-size:.78rem; }
.sn-crumb-root, .sn-crumb-group { color: var(--muted); white-space:nowrap; }
.sn-crumb-divider { color: var(--muted); }
.sn-crumb-current { overflow:hidden; color: var(--ink); font-weight:500; white-space:nowrap; text-overflow:ellipsis; }
.sn-menu-toggle { display:none; }
.sn-account { position:relative; flex-shrink:0; color: var(--ink); font-size:.8rem; }
/* Signed in: the same 44px icon button as the gear, holding the avatar (initial or person icon); name 「账号」 */
.sn-account-toggle { padding:0; font:inherit; }
.sn-account-toggle[aria-expanded="true"] { background: var(--tint-2); border-color: var(--control-line); }
.sn-avatar { display:grid; flex-shrink:0; place-items:center; width:30px; height:30px; border-radius: 50%; color: var(--ink-2); font-size:.8rem; font-weight:500; }
.sn-avatar:has(#accountInitial:not([hidden])) { background: var(--note-cream); }
.sn-avatar .sn-icon { display:block; width:22px; height:22px; }
.sn-account-panel { position:absolute; top:calc(100% + 8px); right:0; width:min(288px, calc(100vw - 32px)); max-height:calc(100dvh - 160px); overflow-y:auto; padding:8px; border: 1px solid var(--line); border-radius: 16px; background: var(--surface); color: var(--ink); box-shadow: var(--shadow-float); }
.sn-account [hidden] { display:none !important; }
.sn-account-intro { padding:8px 10px; overflow-wrap:anywhere; }
.sn-account-intro strong { font-size:.9rem; font-weight:500; }
.sn-account-intro p { margin:4px 0 0; color: var(--muted); font-size:.75rem; line-height:1.6; }
.sn-account-item { display:flex; align-items:center; gap:8px; width:100%; min-height:44px; padding:10px; border: 0; border-radius: 8px; background: transparent; color: var(--ink) !important; font:inherit; line-height:1.5; text-align:left; text-decoration:none; overflow-wrap:anywhere; cursor:pointer; }
.sn-account-item:hover { background: var(--tint-1); }
.sn-account-item:disabled { opacity:.65; cursor:wait; }
.sn-account-email { margin:8px 10px; padding-top:12px; border-top: 1px solid var(--line); color: var(--muted); font-size:.72rem; line-height:1.6; overflow-wrap:anywhere; }
.sn-account-message { margin:6px 10px; color: var(--bad); font-size:.75rem; line-height:1.6; }
.sn-account-toggle:focus-visible, .sn-account-item:focus-visible { outline: 2px solid var(--accent-focus); outline-offset:2px; }

.sn-local, .sn-mobile { display:none; }

/* "Continue where you left off" chip under the page heading, and the highlight on the restored card */
.sn-resume-chip { display:inline-flex; align-items:center; min-height:44px; margin:0 0 14px; padding:8px 16px; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); color: var(--color-link); font:inherit; font-size:.88rem; cursor:pointer; box-shadow: none; }
.sn-resume-chip:hover { background: var(--tint-1); }
.sn-resume-chip + .sn-resume-chip { margin-left: 8px; }
.sn-continue { max-width: 100%; }
.sn-continue span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 「从头开始」 beside it is the quieter text tier: no border or fill */
.sn-continue + .sn-start-over { padding-inline: 8px; border-color: transparent; background: transparent; color: var(--muted); }
.sn-continue + .sn-start-over:hover { background: transparent; text-decoration: underline; text-underline-offset: 4px; }
.sn-resume-chip:focus-visible { outline: 2px solid var(--accent-focus); outline-offset: 2px; }
.sn-resume-flash { outline: 2px solid var(--color-accent-deco); outline-offset:4px; }

/* Keep floating widgets clear of the sidebar (drag positions set inline still win) */
body.has-app-nav .writing-board, body.has-app-nav .writing-launcher { left:calc(var(--sn-sidebar-width) + 16px); }

/* One page frame across Learn, Practice, Review, Today and Settings.
   A companion rail is internal padding, never a different page width/left edge. */
body.has-app-nav :is(.app, .settings-app, .app-layout) {
  width: min(var(--layout-content-max), calc(100% - 2 * var(--layout-gutter)));
  min-width: 0;
  margin-left: auto;
  margin-right: auto;
  padding-top: var(--space-5);
}
body.has-app-nav .app-layout { margin-top: 0; gap: var(--space-5); grid-template-columns: 240px minmax(0, 1fr); }
body.has-app-nav .app-layout > * { min-width: 0; }
body.has-app-nav :is(.app, .settings-app, .app-layout) .page-header { margin: 4px 0 var(--space-5); }

/* Desktop: Sandy's dock (assets/sandy.css) lives in a companion rail on the right. The rail is internal padding,
   so the content's left edge never moves and nothing in the dock can sit on text or answers.
   has-sandy-dock is set by assets/sandy.js; :has() covers the first paint on pages with their own Sandy. */
@media (min-width:901px) {
  body.has-app-nav:is(.has-sandy-dock, :has(.floating-sandy-toggle, #sandy)) :is(.app, .settings-app, .app-layout, .support-app, .contact-app) { padding-right: var(--layout-companion-rail); }
}
@media (min-width:901px) and (max-width:1170px) {
  :root { --sn-sidebar-width: 220px; }
  .sn-sidebar { --sn-pad-x:12px; }
}
/* Short desktop windows (≤920px tall, e.g. a 1280×800 laptop): compact rows so the whole menu, with 「更多」 open too, fits
   without scrolling. Rows stay ≥40px (pointer screens). The sidebar still scrolls (overflow-y:auto) if a window is shorter still. */
@media (max-height:920px) and (min-width:901px) {
  .sn-sidebar { --sn-pad-t:14px; --sn-pad-x:12px; padding-bottom:8px; }
  .sn-overview { padding-bottom:6px; }
  .sn-section { margin-top:6px; }
  .sn-section + .sn-section { margin-top:6px; padding-top:6px; }
  .sn-side-link { min-height:40px; margin:0; padding-top:8px; padding-bottom:8px; }
  .sn-more { padding-top:6px; }
}

@media (max-width:900px) {
  body.has-app-nav { padding-left:0; padding-bottom:calc(var(--sn-bottom-bar) + env(safe-area-inset-bottom, 0px)); }
  body.has-app-nav .app-layout { grid-template-columns: minmax(0, 1fr); }
  :root { --sn-bar: 64px; }
  html { scroll-padding-top:120px; }
  .sn-topbar { min-height:calc(var(--sn-bar) + 1px); padding:10px 16px; gap:10px; background: var(--study-background, var(--page-1)); }
  .sn-crumbs { flex:1; gap:8px; font-size: .75rem; }
  .sn-crumb-group { display:none; }
  .sn-menu-toggle { display:inline-flex; flex-shrink:0; align-items:center; justify-content:center; width:44px; height:44px; border: 1px solid var(--line); border-radius: var(--radius-control); background: var(--surface); color: var(--ink); cursor:pointer; }

  /* The ☰ panel: a paper sheet with a hairline edge and one soft shadow (≤ .24; dark: none, the --border edge shows) and a 20px
     notepad strip along its top (a 6px one disappears into the 20px corners). Behind it, from under the top bar (the ✕ stays clear), a scrim of the band colour at 78%:
     a .sn-topbar pseudo so it sits under the panel and over the page tabs. Tapping it closes the menu (assets/nav.js). */
  .sn-sidebar { --sn-band-h:20px; --sn-pad-t:12px; --sn-pad-x:18px; display:none; inset:calc(var(--sn-bar) + 4px) 12px auto; width:auto; max-height:calc(100dvh - 160px); padding:calc(var(--sn-band-h) + 1px + var(--sn-pad-t)) var(--sn-pad-x) var(--sn-pad-x); border: 1px solid var(--border); border-radius: var(--radius-dialog); box-shadow: var(--shadow-menu-float, var(--shadow-float)); z-index:28; }
  .sn-open .sn-sidebar { display:flex; }
  .sn-open .sn-topbar::after { content:""; position:fixed; inset:calc(var(--sn-bar) + 1px) 0 0; background: color-mix(in oklab, var(--color-menu-band, var(--page-1)) 78%, transparent); pointer-events:auto; }
  .sn-side-nav { display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:12px; }
  /* 今天 is the first tab of the bottom bar, so the ☰ panel starts with the study pages */
  .sn-overview { display:none; }
  /* 601–900px: the three groups sit side by side, so the columns separate them and no hairline is needed */
  .sn-section, .sn-section + .sn-section { margin:0; padding-top:0; border-top:0; }
  .sn-side-link { gap:8px; padding:10px 8px; font-size:.8rem; }
  .sn-more { margin-top:12px; }
  .sn-more-toggle { padding:0 8px; }
  .sn-more-links .sn-side-link { padding:9px 8px; }
  /* Sandy stays with the learner while the menu is open (owner, 2026-10-12); only floating layers that would cover the panel step aside */
  .sn-open :is(.floating-progress, .floating-sandy-bubble, .sandy-bubble, .sandy-pack.is-popover, .writing-board, .writing-launcher) { visibility:hidden; }

  .sn-local { display:flex; gap:8px; padding:10px 16px; overflow-x:auto; border-bottom: 1px solid var(--border); background: var(--study-background, var(--page-1)); scrollbar-width:none; }
  .sn-local::-webkit-scrollbar { display:none; }
  .sn-local:not(.is-end) { -webkit-mask-image:linear-gradient(90deg, #000 calc(100% - 32px), transparent); mask-image:linear-gradient(90deg, #000 calc(100% - 32px), transparent); }
  /* symmetric 12px control corners (2026-10-12), not the asymmetric sticky-note chip, so tabs match the calm page controls */
  .sn-local a { position:relative; display:inline-flex; align-items:center; min-height:44px; padding:7px 12px; border-radius: var(--radius-control); color: var(--muted); font-size:.8rem; text-decoration:none; white-space:nowrap; }
  /* Section tabs: the current one is a pale apricot sticky note like the selected chip, with a 1px edge and weight 500
     so it's never marked by colour alone */
  .sn-local a[aria-current="page"] { background: var(--color-selected); color: var(--color-on-selected); box-shadow: inset 0 0 0 1px var(--color-selected-line); font-weight:500; }

  .sn-mobile { position:fixed; inset:auto 0 0; z-index:35; display:grid; grid-template-columns:repeat(4, 1fr); padding:7px 12px calc(7px + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--border); background: var(--surface); }
  .sn-mobile a { position:relative; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px; min-height:47px; padding:5px; border-radius: 10px; color: var(--muted); font-size:.7rem; text-decoration:none; }
  /* Active tab: ink label, medium weight and a short Sandy-orange underline under it (no filled pill). An underline,
     not a dot (owner, 2026-10-12: a dot read as "the next step", not "you are here") */
  .sn-mobile a[aria-current] { color: var(--ink); font-weight:500; }
  .sn-mobile a[aria-current]::after { content:""; position:absolute; left:50%; bottom:1px; width:20px; height:3px; margin-left:-10px; border-radius:2px; background: var(--color-accent-deco); }
  .sn-mobile .sn-icon { width:24px; height:24px; }

  /* Sandy's dock on phones: the right end of the tab bar (positions in assets/sandy.css). The tabs keep that space free,
     so Sandy and her 💤 button never sit on a card, a choice or a line of text, at any scroll position. */
  body.has-app-nav:is(.has-sandy-dock, :has(.floating-sandy-toggle, #sandy)) .sn-mobile { padding-right:calc(var(--dock-bar-reserve) + env(safe-area-inset-right, 0px)); }
  /* No permanent bubbles or progress pill on phones: the dock only holds Sandy and 💤 */
  .floating-progress, .floating-sandy-bubble, .floating-sandy-status { display:none !important; }

  /* Lift the writing board above the bottom tab bar */
  body.has-app-nav .writing-board, body.has-app-nav .writing-launcher { left:12px; bottom:calc(var(--sn-bottom-bar) + 16px + env(safe-area-inset-bottom, 0px)); }
}
@media (max-width:700px) {
  /* The write board is for iPad / pen use; on phones it only covers the word list */
  .writing-board, .writing-launcher { display:none !important; }
}
@media (max-width:600px) {
  .sn-side-nav { grid-template-columns:1fr; gap:0; }
  .sn-section + .sn-section { margin-top:8px; padding-top:8px; border-top: 1px solid var(--border); }
  .sn-side-link, .sn-more-links .sn-side-link { padding:10px 12px; }
  .sn-more-toggle { padding:0 12px; }
  .sn-sidebar { max-height:calc(100dvh - 150px); }
}

/* Settings is available in the account disclosure and the main navigation. */
.sn-crumbs { flex: 1; }
.sn-icon-btn { display: inline-grid; flex-shrink: 0; place-items: center; width: 44px; height: 44px; border: 1px solid var(--border); border-radius: var(--radius-control); background: var(--surface); color: var(--ink-2); cursor: pointer; }
.sn-icon-btn:hover { background: var(--tint-2); }
.sn-settings { text-decoration:none; }
.sn-icon-btn:focus-visible { outline: 2px solid var(--accent-focus); outline-offset: 2px; }
@media (max-width:600px) {
  .sn-crumb-root, .sn-crumb-divider { display:none; }
}

/* Account entry (auth-nav): a 44px Settings gear beside one 44px account icon: a link named 「登录 / 注册」 for signed-out
   learners, the avatar button 「账号」 once signed in (assets/account.js swaps them once the session is known). */
.sn-gear[aria-current="page"] { background: var(--tint-3); border-color: var(--control-line); }
.sn-signin { text-decoration:none; }
.sn-account-intro + .sn-account-email { margin:0 10px 8px; padding-top:0; border-top:0; }

/* Wide screens: hide / show the sidebar (toggle at the far left of the top bar, assets/nav.js).
   html.sn-sidebar-collapsed is set before the first paint from n2-sidebar-collapsed-v1. Collapsing sets
   --sn-sidebar-width to 0 on the body, so everything that lines up with the sidebar (body padding, the write board,
   the share toast, Sandy's note toast, the quiz feedback sheet) follows on its own. Phones (≤900px) never read it. */
.sn-collapse-toggle { display:none; }
@media (min-width:901px) {
  .sn-collapse-toggle { display:inline-grid; margin-left:-8px; }
  html.sn-sidebar-collapsed body.has-app-nav { --sn-sidebar-width:0px; }
  /* The menu keeps its own width while it slides out; visibility also takes its links out of the tab order */
  html.sn-sidebar-collapsed body.has-app-nav .sn-sidebar { width:248px; transform:translateX(-100%); visibility:hidden; }
  html.sn-sidebar-animating body.has-app-nav { transition:padding-left .2s ease; }
  html.sn-sidebar-animating body.has-app-nav .sn-sidebar { transition:transform .2s ease, visibility 0s linear 0s; }
  html.sn-sidebar-animating.sn-sidebar-collapsed body.has-app-nav .sn-sidebar { transition:transform .2s ease, visibility 0s linear .2s; }
}
@media (min-width:901px) and (max-width:1170px) {
  html.sn-sidebar-collapsed body.has-app-nav .sn-sidebar { width:220px; }
}
@media (prefers-reduced-motion: reduce) {
  html.sn-sidebar-animating body.has-app-nav, html.sn-sidebar-animating body.has-app-nav .sn-sidebar { transition:none !important; }
}
