/* page-shell.css: the collapsible sidebar (spec/page-shell.md; screens/shell.SCREEN.md).
   Expanded is the 240 sidebar of system 7. Collapsed is a 48 icon rail (56 under a coarse pointer):
   the toggle alone at the top (C79), 32 tiles at the same icon x as the expanded rows, the "Campus" label as a
   1px rule (S12), theme above account at the foot (C79). html.rail is set by the head script and shell.js:
   at 1024 and up from the stored choice, at 768 to 1023 whenever the overlay is shut. Phones keep the drawer. */

@property --sidebar { syntax: '<length>'; inherits: true; initial-value: 240px; }
/* the rail's ease is the rail spring from motion.js (.smooth(duration: 0.14), sampled linear(), settles in 206 ms,
   so the 200 ms below is its whole curve; spec/motion-apple-springs.md 3, owner 2 Nov 2026: Apple springs only) */
:root { --rail: 48px; --rail-ease: var(--dm-rail-ease, linear); }
@media (pointer: coarse) { :root { --rail: 56px; } }

/* width and the grid's first column move as one, 200ms (spec 8; dibs choice, the drawer's .2s) */
html { transition: --sidebar .2s var(--rail-ease); }
html.rail { --sidebar: var(--rail); }
#sidebar { overflow-x: hidden; }

/* top row: wordmark, then the toggle at the row's right end (C6, A27); the toggle alone when collapsed (C79) */
.side-top { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); flex-shrink: 0; height: 28px; }
#side-toggle { width: 32px; height: 32px; min-height: 32px; flex-shrink: 0; color: var(--muted); }
#side-toggle:hover { color: var(--ink); }
/* only the sidebar's wordmark folds with the rail; the bare frames (sign in, email landings, error) keep theirs at 1024 */
html.rail .side-top .wordmark { display: none; }

/* term picker: one tap away in the rail; its row closes with the width (spec 6). The 4px pad keeps the
   select's focus ring inside the clip. */
.term-switch {
  flex-shrink: 0; max-height: 40px; overflow: hidden; padding: var(--s-1); margin: var(--s-2) calc(-1 * var(--s-1)) calc(-1 * var(--s-1));
  transition: max-height .2s var(--rail-ease), margin .2s var(--rail-ease), padding .2s var(--rail-ease), opacity .1s var(--rail-ease) .1s, visibility 0s;
}
.term-switch .icon { right: 12px; }
html.rail .term-switch {
  max-height: 0; margin-top: 0; margin-bottom: 0; padding-top: 0; padding-bottom: 0; opacity: 0; visibility: hidden;
  transition: max-height .2s var(--rail-ease), margin .2s var(--rail-ease), padding .2s var(--rail-ease), opacity .1s var(--rail-ease), visibility 0s .2s;
}

/* rows: labels clip, never wrap, and fade in the first 100ms of a collapse (last 100ms of an expand) */
#nav a, a.account-row { position: relative; overflow: hidden; white-space: nowrap; }
.nav-text, .account-name { transition: opacity .1s var(--rail-ease) .1s; }
html.rail .nav-text, html.rail .account-name { opacity: 0; transition: opacity .1s var(--rail-ease); }

/* the "Campus" label becomes a 1px rule 8 in from both rail edges (S12) */
.nav-label {
  height: 38px; overflow: hidden; white-space: nowrap;
  transition: height .2s var(--rail-ease), padding .2s var(--rail-ease), margin .2s var(--rail-ease), background-color .2s var(--rail-ease), color .1s var(--rail-ease);
}
html.rail .nav-label { height: 1px; padding: 0; margin: var(--s-2) 0; background: var(--line); color: transparent; }
html.rail .nav-rule { margin: var(--s-2) 0; }

/* unread: one 6px accent dot on Class chats only (SE13, C5) */
.nav-dot { position: absolute; top: 13px; right: 12px; width: 6px; height: 6px; border-radius: var(--r-pill); background: var(--accent); }
html.rail .nav-dot { top: 5px; right: 5px; box-shadow: 0 0 0 1.5px var(--bg); }

/* foot: expanded keeps the account row with the theme button over its right end; the rail stacks the
   theme tile above the account tile, 4 apart (C79) */
.sidebar-foot > #theme { position: relative; z-index: 1; }
.signin-btn .icon { display: none; }
html.rail .sidebar-foot { display: flex; flex-direction: column; align-items: stretch; gap: var(--s-1); }
html.rail .sidebar-foot > #theme { margin-right: 0; }
html.rail .sidebar-foot > .account-slot { flex: none; margin-right: 0; }
html.rail a.account-row { height: 32px; min-height: 32px; padding: 0 var(--s-2); }
html.rail .signin-btn {
  justify-content: flex-start; width: 100%; height: 32px; min-height: 32px; padding: 0 var(--s-2);
  border-color: transparent; background: transparent; color: var(--muted);
}
html.rail .signin-btn:hover { background: var(--surface-2); color: var(--ink); }
html.rail .signin-btn .icon { display: block; }
html.rail .signin-btn > span { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* rail tip for the toggle: label, then the two key chips (A27) */
.rail-tip-keys { display: inline-flex; align-items: center; gap: var(--s-2); }
.rail-tip-keys > span { display: inline-flex; gap: 2px; }

/* 44 touch targets (dibs.css 13): the term row grows to match */
@media (pointer: coarse), (max-width: 599px) { .term-switch { max-height: 52px; } }

/* coarse pointer: 56 rail, 44 tiles with 6 sides; the icon sits at x 20 (spec 6) */
@media (pointer: coarse) {
  #side-toggle { width: 44px; height: 44px; min-height: 44px; margin: -8px 0; }
  .nav-dot { top: 19px; }
  html.rail #sidebar { padding-left: 6px; padding-right: 6px; }
  html.rail #nav a, html.rail a.account-row, html.rail .signin-btn { padding: 0 14px; }
  html.rail a.account-row, html.rail .signin-btn { height: 44px; min-height: 44px; }
  html.rail .sidebar-foot > #theme { width: 44px; }
  html.rail .nav-dot { top: 9px; right: 9px; }
  html.rail .nav-label, html.rail .nav-rule { margin-left: 2px; margin-right: 2px; }
}

/* 768 to 1023: the rail replaces the 48px hamburger bar; expanding lays the 240 sidebar over the page
   with the scrim, and it closes on Escape, scrim or navigation (spec 5, 10) */
@media (min-width: 768px) and (max-width: 1023px) {
  .shell { margin-left: var(--rail); }
  body.menu-open #sidebar { box-shadow: var(--shadow-overlay); }
  body.menu-open .nav-scrim {
    display: block; position: fixed; inset: 0; z-index: 25;
    width: 100%; height: 100%; min-height: 0; padding: 0;
    border: 0; border-radius: 0; background: var(--scrim);
  }
  body.menu-open { overflow: hidden; }
  /* no top bar in this band: sticky heads pin to the top, and Ask's own menu button is not needed */
  .disc-sticky, .wk-head, .ch-list-head, .ch-pane-head { top: 0; }
  .chats { min-height: calc(100dvh - 33px); }
  .ask-nav { display: none; }
}

/* phones: the hamburger and drawer as built; the drawer has no collapse toggle (spec 10) */
@media (max-width: 767px) {
  #side-toggle { display: none; }
}

/* the nav list is the scroll region; the top row, term picker and foot stay put, so theme and account are
   always on screen on short touch screens (SL78). The 4px pad keeps focus rings inside the clip. */
#sidebar { overflow: hidden; }
#nav { flex: 1 1 auto; min-height: 0; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; padding: var(--s-1); margin: var(--s-3) calc(-1 * var(--s-1)) 0; }
#nav > * { flex-shrink: 0; }
.sidebar-foot { flex-shrink: 0; }
/* the whole sidebar scrolls and the foot follows Pricing (spec 4), so no row hides under a pinned foot
   (L264 shows the full list with no hidden tail). Phones, every touch screen (44 rows need about 880, spec 4),
   and the 768 to 1023 rail and overlay, whose short fine-pointer windows (800x600) also overflow. Fine-pointer
   laptops from 1024 keep the pinned foot above. The foot keeps margin-top auto, so it still sits at the
   bottom whenever the list fits. The rail hides the bar so it never narrows the 48 or 56 tiles. */
@media (max-width: 1023px), (pointer: coarse) {
  #sidebar { overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; }
  #nav { flex: none; overflow: visible; }
  html.rail #sidebar { scrollbar-width: none; }
  html.rail #sidebar::-webkit-scrollbar { display: none; }
  /* the foot pins to the bottom of the scroller, so theme and account stay on screen (SL78) while the list
     scrolls under it; at the end of the list it sits in flow after Pricing again */
  #sidebar { padding-bottom: 0; }
  .sidebar-foot { position: sticky; bottom: 0; z-index: 2; background: var(--bg); padding-bottom: var(--s-3); }
}

/* scroll cue: whenever the list runs past the foot, a 1px --line rule tops the foot and the list fades into
   --bg above it, so the row there reads as cut, not as the end (SL78 account always visible; L264 no hidden
   tail). The fade is one row pitch plus 2 (46 + 2 coarse, 34 + 2 fine), so whatever the scroll position some
   row always crosses it; a shorter fade could land on the gap between rows and leave a whole row sitting clean
   above the rule. shell.js sets #sidebar.side-more from the scroller's position. The foot spans the full
   sidebar width so the rule meets both edges; the rule is an inset shadow, so it never moves a row.
   Fine-pointer laptops from 1024 scroll #nav alone and keep the soft #nav edges at the end of this file. */
@media (max-width: 1023px), (pointer: coarse) {
  #sidebar { --side-pad: var(--s-2); --fade-h: 36px; }
  .sidebar-foot { margin-left: calc(-1 * var(--side-pad)); margin-right: calc(-1 * var(--side-pad)); padding-left: var(--side-pad); padding-right: var(--side-pad); transition: box-shadow var(--dm-rail-ms, 206ms) var(--rail-ease); }
  .sidebar-foot::before {
    content: ''; position: absolute; left: 0; right: 0; bottom: 100%; height: var(--fade-h);
    background: linear-gradient(to bottom, transparent, var(--bg)); opacity: 0; pointer-events: none;
    transition: opacity var(--dm-rail-ms, 206ms) var(--rail-ease);
  }
  #sidebar.side-more .sidebar-foot { box-shadow: inset 0 1px 0 var(--line); }
  #sidebar.side-more .sidebar-foot::before { opacity: 1; }
}
@media (pointer: coarse) { #sidebar { --fade-h: 48px; } html.rail #sidebar { --side-pad: 6px; } }

/* light rail: the active tile is the only sign of the page, so it steps one shade further than hover,
   --line on --bg, about the S12 Home tile's step. Dark already has that step on --surface-2 (S12, C79 measured) */
html.rail[data-theme="light"] #nav a.active, html.rail[data-theme="light"] a.account-row.active { background: var(--line); }
@media not all and (prefers-color-scheme: dark) {
  html.rail:not([data-theme="dark"]) #nav a.active, html.rail:not([data-theme="dark"]) a.account-row.active { background: var(--line); }
}

/* collapsing gives the content the 192 the sidebar returned: the shared column cap grows by the same
   amount, so Plan's week grid and Discover's list fill the width beside the rail (A28, S12) */
main { transition: max-width .2s var(--rail-ease); }
@media (min-width: 1024px) {
  html.rail main { max-width: calc(var(--w-list) + 2 * var(--s-8) + 240px - var(--rail)); }
}

/* owner 18 Oct: no native scrollbar in the sidebar, expanded or rail (it narrowed the rail tiles and read as
   browser chrome). The list still scrolls by wheel, touch and keyboard; the cue is a soft edge that appears
   only while rows are hidden above or below (local and scroll backgrounds), as Linear and Slack sidebars show
   no bar at rest. */
#nav, #sidebar { scrollbar-width: none; }
#nav::-webkit-scrollbar, #sidebar::-webkit-scrollbar { display: none; }
#nav {
  background:
    linear-gradient(var(--bg) 40%, transparent) top / 100% 20px no-repeat local,
    linear-gradient(transparent, var(--bg) 60%) bottom / 100% 20px no-repeat local,
    linear-gradient(var(--line), transparent) top / 100% 8px no-repeat scroll,
    linear-gradient(transparent, var(--line)) bottom / 100% 8px no-repeat scroll;
  background-color: var(--bg);
}
@media (max-width: 1023px), (pointer: coarse) {
  #nav { background: none; }
}

/* the foot is sticky where the whole sidebar scrolls, so focus scrolling must stop above it and above the
   fade: shell.js writes the foot's height to --foot-h (64 to 68 expanded, 92 to 116 in the rail, where theme
   sits over account); 116 is the tallest foot, for the first paint. */
@media (max-width: 1023px), (pointer: coarse) {
  #sidebar { scroll-padding-bottom: calc(var(--foot-h, 116px) + var(--fade-h) + 4px); }
}

/* owner 18 Oct: theme change bleeds across the page from the toggle (app.js themeSwap) */
html.vt-theme::view-transition-old(root),html.vt-theme::view-transition-new(root){animation:none;mix-blend-mode:normal}
html.vt-theme::view-transition-new(root){z-index:2}
html.vt-theme *,html.vt-theme *::before,html.vt-theme *::after{transition:none!important}
