/* endmin's only stylesheet. One hand-written file, no framework, no build
   step, no CDN.

   The token set, the control shapes and the motion are lifted from the mail
   app at /srv/email so the two feel like one system on this box. Dark only:
   there is no light palette and no theme switch, because a terminal is dark
   and a light chrome wrapped around a dark terminal never stopped looking
   like an accident. */

/* ------------------------------------------------------------------- font
   Commit Mono 1.143, vendored under the SIL OFL (see vendor/). Self-hosted
   rather than pulled from a CDN, because script-src/style-src are 'self' and
   because a terminal that waits on someone else's network to draw text is not
   a terminal. Only the four faces xterm can ask for: the browser fetches bold
   or italic only when the pty actually emits SGR 1 or 3.

   The paths are relative, so they resolve under the versioned /static/v-<hash>
   prefix this file is served from and inherit its cache lifetime. */

@font-face {
  font-family: "Commit Mono";
  src: url("vendor/CommitMono-400-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Commit Mono";
  src: url("vendor/CommitMono-400-Italic.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
}
@font-face {
  font-family: "Commit Mono";
  src: url("vendor/CommitMono-700-Regular.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Commit Mono";
  src: url("vendor/CommitMono-700-Italic.woff2") format("woff2");
  font-weight: 700; font-style: italic; font-display: swap;
}

/* ------------------------------------------------------------------ tokens */

:root {
  color-scheme: dark;

  --bg:          #0f1216;
  --surface:     #161a20;
  --surface-2:   #1c2128;
  --surface-3:   #252b34;
  --border:      #262c35;
  --border-2:    #333b46;
  --text:        #e7eaf0;
  --text-soft:   #9aa3b2;
  --text-faint:  #7b8494;
  --accent:      #5b9dff;
  --accent-ink:  #08111f;
  --accent-soft: #17233a;
  --danger:      #ff6b6b;
  --ok:          #4ade80;
  --warn:        #f0b429;
  --shadow-sm:   0 1px 2px rgba(0, 0, 0, .4);
  --shadow-md:   0 8px 28px rgba(0, 0, 0, .55);
  --radius:      10px;
  --radius-sm:   7px;

  /* Motion. One place to slow everything down, and one place for the
     reduced-motion block to switch it all off. */
  --dur-fast: 120ms;
  --dur:      190ms;
  --dur-slow: 280ms;
  --ease:     cubic-bezier(.2, .7, .3, 1);
  --ease-out: cubic-bezier(0, 0, .2, 1);

  /* The terminal's own colours. term-xterm.js reads these back out with
     getComputedStyle and hands them to xterm as its theme, so the terminal
     palette lives in css like every other colour in the app. */
  --term-bg: #0c0f13;
  --term-fg: #dde2ea;
  --term-cursor: #5b9dff;
  --term-sel: rgba(91, 157, 255, .32);

  --ansi-black: #2a313b;         --ansi-bright-black: #5b6472;
  --ansi-red: #ff6b6b;           --ansi-bright-red: #ff9490;
  --ansi-green: #4ade80;         --ansi-bright-green: #7ff0a5;
  --ansi-yellow: #f0b429;        --ansi-bright-yellow: #ffd166;
  --ansi-blue: #5b9dff;          --ansi-bright-blue: #8bb9ff;
  --ansi-magenta: #c48cff;       --ansi-bright-magenta: #dcb6ff;
  --ansi-cyan: #45d0d8;          --ansi-bright-cyan: #6fe3ea;
  --ansi-white: #c2c9d4;         --ansi-bright-white: #eef1f6;

  /* Geometry. Tokens rather than magic numbers, because the terminal's height
     falls out of these and the two must never drift apart. */
  --rail-w: 216px;
  --topbar-h: 48px;
  --termbar-h: 46px;
  /* Two rows of 38px keys, plus the 6px gutter and 5px of padding each side. */
  --keybar-h: 92px;
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
  /* The home-bar inset belongs to the key bar: on a phone it is the last row
     on screen, with nothing fixed below it. */
  --kb-safe: var(--safe-b);

  /* Published by viewport.js onto <html>. Declared here too, because a calc()
     against an undefined custom property makes the whole declaration invalid
     and the page would have no height at all before script runs. */
  --vvh: 100vh;
  --kb: 0px;

  --sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: "Commit Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, "DejaVu Sans Mono", monospace;
}

@media (prefers-reduced-motion: reduce) {
  :root { --dur-fast: 0ms; --dur: 0ms; --dur-slow: 0ms; }
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}

/* ------------------------------------------------------------------- base */

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  /* No pull-to-refresh. A swipe up in the terminal must never reload the page
     and destroy the view of a running session. */
  overscroll-behavior: none;
}

body {
  font: 14px/1.5 var(--sans);
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3 { margin: 0 0 8px; font-weight: 600; line-height: 1.25; }
p { margin: 0 0 10px; }
strong { font-weight: 650; }
code, pre { font-family: var(--mono); font-size: .92em; }
code { color: var(--text); }
pre {
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 10px 12px; overflow-x: auto;
}
ul { margin: 0 0 10px; padding-left: 20px; }
li { margin-bottom: 3px; }
.muted { color: var(--text-soft); font-size: 13px; }
.icon { width: 17px; height: 17px; stroke-width: 1.9; display: block; flex: 0 0 auto; }
[hidden] { display: none !important; }

/* The <symbol> sprite html.ts prints as the first child of <body>. It carries
   no visible geometry of its own, and it must occupy no space. */
.icon-sprite { display: none; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* --------------------------------------------------------------- controls */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 7px 13px; font: inherit; font-weight: 500; line-height: 1.2;
  border: 1px solid var(--border-2); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text);
  cursor: pointer; white-space: nowrap; touch-action: manipulation;
  transition: background var(--dur-fast), border-color var(--dur-fast),
              transform var(--dur-fast);
}
.btn:hover { background: var(--surface-2); }
.btn:active { background: var(--surface-3); transform: scale(.97); }
.btn:disabled { opacity: .55; cursor: default; transform: none; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn-primary:hover { background: var(--accent); filter: brightness(1.08); }
.btn-primary:active { filter: brightness(.94); }
.btn.danger, .nav-menu-list button.danger { color: var(--danger); }

.icon-button {
  display: grid; place-items: center;
  width: 32px; height: 32px; padding: 0;
  border: 1px solid transparent; border-radius: var(--radius-sm);
  background: transparent; color: var(--text-soft);
  cursor: pointer; touch-action: manipulation;
  transition: background var(--dur-fast), color var(--dur-fast);
}
.icon-button:hover { background: var(--surface-3); color: var(--text); }

input, textarea, select {
  width: 100%; padding: 8px 10px; font: inherit;
  /* 16px is the anti-zoom floor: iOS zooms the page whenever a focused field
     computes under it. */
  font-size: 16px;
  border: 1px solid var(--border-2); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text);
  transition: border-color var(--dur-fast), background var(--dur-fast);
}
input:focus, textarea:focus, select:focus { outline: none; border-color: var(--accent); }
textarea { resize: vertical; line-height: 1.6; }

label { font-weight: 500; }
.field { display: block; margin: 0 0 12px; }
.field > span { display: block; margin-bottom: 5px; font-size: 13px; font-weight: 400; color: var(--text-soft); }

/* A form is read left to right on a laptop but must not stretch a password
   field across a 27 inch monitor. */
.form-narrow { max-width: 340px; }

.notice {
  padding: 9px 11px; margin: 0 0 12px;
  border-radius: var(--radius-sm); font-size: 13px;
  animation: notice-in var(--dur) var(--ease-out);
}
.notice-ok { background: color-mix(in srgb, var(--ok) 13%, transparent); color: var(--ok); }
.notice-bad { background: color-mix(in srgb, var(--danger) 13%, transparent); color: var(--danger); }
@keyframes notice-in { from { opacity: 0; transform: translateY(-4px); } }

/* -------------------------------------------------------------- the shell */

.shell {
  display: grid;
  grid-template-columns: var(--rail-w) minmax(0, 1fr);
  /* dvh, not vh: on iOS vh is the tall-URL-bar height, so the bottom of the
     page sits underneath the browser toolbar. */
  height: 100dvh;
  overflow: hidden;
}

.rail {
  grid-column: 1;
  display: flex; flex-direction: column; gap: 2px;
  padding: 12px 10px;
  background: var(--surface); border-right: 1px solid var(--border);
  overflow-y: auto;
}
.rail-brand {
  display: block; padding: 6px 12px 16px;
  font-size: 15px; font-weight: 650; letter-spacing: .2px;
  color: var(--accent);
}
.rail-brand:hover { text-decoration: none; filter: brightness(1.1); }
.rail-items { display: flex; flex-direction: column; gap: 1px; }

/* Pill rows, the same shape the mail app's folder list uses. */
.rail-item {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 12px; border-radius: 999px;
  color: var(--text-soft); user-select: none;
  transition: background var(--dur-fast), color var(--dur-fast);
}
.rail-item:hover { background: var(--surface-3); color: var(--text); text-decoration: none; }
/* The accessibility attribute IS the state. There is no second source of
   truth to keep in sync. */
.rail-item[aria-current="page"] { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.rail-spacer { flex: 1 1 auto; }

.rail-account { margin-top: auto; }
.rail-account > summary {
  display: flex; align-items: center; gap: 6px; justify-content: space-between;
  padding: 9px 12px; border-radius: 999px;
  color: var(--text-soft); cursor: pointer; list-style: none;
  transition: background var(--dur-fast), color var(--dur-fast);
}
.rail-account > summary::-webkit-details-marker { display: none; }
.rail-account > summary:hover { background: var(--surface-3); color: var(--text); }

.nav-menu { position: relative; }
.nav-menu-list {
  position: absolute; bottom: 100%; left: 0; min-width: 190px; z-index: 40;
  display: flex; flex-direction: column; gap: 1px;
  padding: 5px; margin-bottom: 6px;
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border-2); border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  animation: menu-in var(--dur) var(--ease-out);
}
@keyframes menu-in { from { opacity: 0; transform: translateY(6px); } }
.nav-menu-list a, .nav-menu-list button {
  display: block; width: 100%; text-align: left;
  padding: 8px 11px; font: inherit;
  border: 0; border-radius: var(--radius-sm);
  background: none; color: var(--text); cursor: pointer;
  transition: background var(--dur-fast);
}
.nav-menu-list a:hover, .nav-menu-list button:hover { background: var(--surface-3); text-decoration: none; }
.nav-menu-list a[aria-current="page"] { background: var(--accent-soft); color: var(--accent); }
.nav-menu-caret { width: 14px; height: 14px; opacity: .7; }

.main { grid-column: 2; min-width: 0; min-height: 0; overflow-y: auto; }
.pad { padding: 24px 20px 48px; max-width: 780px; }
.page-title { font-size: 20px; margin: 0 0 18px; }
/* A module that owns its whole box: no page padding, no page scroll. */
.main-flush { padding: 0; overflow: hidden; display: flex; }
/* …except when such a module renders an ordinary page of content instead of
   its box, which still has to be able to scroll. */
.main-flush > .pad { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.main-center {
  display: flex; align-items: center; justify-content: center;
  min-height: 100dvh; padding: 20px;
}

/* The phone bar. Hidden here; the rail is the wide-screen navigation. */
.topbar { display: none; }

/* A menu row that carries an icon: the module list inside the burger. */
.nav-menu-list .menu-row {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 11px; font: inherit; text-align: left;
}
.nav-menu-list .menu-row[aria-current="page"] { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.menu-rule { height: 1px; margin: 5px 4px; border: 0; background: var(--border-2); }

/* ------------------------------------------------------------------ cards */

.box {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-sm);
  margin: 0 0 16px;
}
.box-head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; border-bottom: 1px solid var(--border);
}
.box-title { margin: 0; font-size: 13px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--text-faint); }
.box-actions { margin-left: auto; }
.box-body { padding: 16px; }
.box-body > :last-child { margin-bottom: 0; }

.session-list { list-style: none; margin: -6px 0; padding: 0; }
.session-list li + li { border-top: 1px solid var(--border); }
.session-list a {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 4px; color: var(--text);
  transition: color var(--dur-fast);
}
.session-list a:hover { text-decoration: none; color: var(--accent); }
.session-name { font-weight: 550; }
.session-cwd { color: var(--text-faint); font-family: var(--mono); font-size: 12px; margin-left: auto; }
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--ok); flex: 0 0 auto; }

/* ------------------------------------------------------------------ login */

.login {
  width: min(380px, 100%); padding: 26px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-md);
  animation: dialog-in var(--dur-slow) var(--ease);
}
.login-title { margin: 0 0 20px; font-size: 19px; text-align: center; color: var(--accent); }
.login-error {
  padding: 9px 11px; margin-bottom: 14px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--danger) 13%, transparent);
  color: var(--danger); font-size: 13px;
  animation: notice-in var(--dur) var(--ease-out);
}
.login .btn { width: 100%; margin-top: 6px; }

/* --------------------------------------------------------------- terminal */

.term {
  display: flex; flex-direction: column;
  flex: 1 1 auto;
  /* The flexbox rule everyone forgets. Without it the screen refuses to shrink
     and overflows the shell, which on a phone puts the key bar off screen. */
  min-height: 0;
  min-width: 0;
  background: var(--term-bg);
  position: relative;
}

.term-bar {
  display: flex; align-items: center; gap: 8px;
  flex: 0 0 auto; height: var(--termbar-h);
  padding: 0 10px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.term-sessions > summary {
  display: flex; align-items: center; gap: 5px;
  padding: 6px 10px; border-radius: var(--radius-sm);
  cursor: pointer; list-style: none; font-weight: 600;
  max-width: 40vw; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  transition: background var(--dur-fast);
}
.term-sessions > summary::-webkit-details-marker { display: none; }
.term-sessions > summary:hover { background: var(--surface-2); }
.term-sessions .nav-menu-list { top: 100%; bottom: auto; margin: 6px 0 0; }
.term-cwd {
  color: var(--text-faint); font-family: var(--mono); font-size: 12px;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}

.term-state {
  font-size: 12px; font-weight: 500; padding: 3px 10px; border-radius: 999px;
  background: var(--surface-3); color: var(--text-soft); white-space: nowrap;
  transition: background var(--dur), color var(--dur);
}
.term-state[data-state="open"] { background: var(--accent-soft); color: var(--accent); }
.term-state[data-state="offline"],
.term-state[data-state="error"] {
  background: color-mix(in srgb, var(--danger) 15%, transparent); color: var(--danger);
}
.term-state[data-state="exited"] {
  background: color-mix(in srgb, var(--warn) 15%, transparent); color: var(--warn);
}
.term-state[data-state="stopped"] {
  background: color-mix(in srgb, var(--danger) 15%, transparent); color: var(--danger);
  cursor: pointer;
}
.term-state[data-state="stopped"]:hover { text-decoration: underline; }

.term-screen {
  flex: 1 1 auto; min-height: 0;
  padding: 6px 4px 6px 8px;
  /* A swipe that reaches the top of the scrollback must not turn into a
     pull-to-refresh on the page behind it. */
  overscroll-behavior: contain;
}
.term-screen .xterm { height: 100%; }
.term-screen .xterm-viewport { background-color: transparent !important; }

/* Input is visibly dead while the socket is down, and it is obvious why:
   keystrokes are dropped rather than queued, because replaying them into a
   Claude Code prompt that has moved on could approve a tool call nobody read. */
.term[data-conn="offline"] .term-screen,
.term[data-conn="stopped"] .term-screen,
.term[data-conn="reconnecting"] .term-screen {
  opacity: .55; pointer-events: none;
  transition: opacity var(--dur);
}

.term-search {
  flex: 0 0 auto; padding: 7px 10px;
  background: var(--surface-2); border-bottom: 1px solid var(--border);
}
.term-search input { background: var(--surface); }

.term-drop {
  position: absolute; inset: 0; z-index: 20;
  display: none; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border: 2px dashed var(--accent);
  font-weight: 600; pointer-events: none;
}
.term[data-drop="over"] .term-drop { display: flex; animation: fade-in var(--dur-fast) var(--ease-out); }
@keyframes fade-in { from { opacity: 0; } }
.term-drop span {
  padding: 9px 18px; border-radius: 999px;
  background: var(--accent); color: var(--accent-ink);
  box-shadow: var(--shadow-md);
}

/* ------------------------------------------------------------- the key bar
   Shown by capability, not by width: a tablet at 1400px with a touchscreen
   wants it, a 700px desktop window does not. */

.term-keys { display: none; }

@media (pointer: coarse) {
  .term-keys[data-role="keybar"]:not([hidden]) {
    display: flex; flex: 0 0 auto; flex-direction: column; gap: 6px;
    height: calc(var(--keybar-h) + var(--kb-safe));
    padding: 5px 6px calc(5px + var(--kb-safe));
    background: var(--surface); border-top: 1px solid var(--border);
    /* Fixed columns, so nothing here scrolls or swallows a drag. */
    touch-action: manipulation;
  }
}

/* Seven equal columns: every key the same width whatever the phone, and no key
   pushed off the edge on a 320px screen. */
.tkey-row {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px;
  min-width: 0;
}

.tkey {
  display: flex; align-items: center; justify-content: center; gap: 2px;
  min-width: 0; height: 38px; padding: 0 2px;
  font-family: var(--mono); font-size: 13px; font-weight: 500;
  border: 1px solid var(--border-2); border-radius: var(--radius-sm);
  background: var(--surface-2); color: var(--text);
  /* Kills the 300ms tap delay and double-tap-to-zoom on the bar. */
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  user-select: none; cursor: pointer;
  transition: background var(--dur-fast), transform var(--dur-fast);
}
.tkey .icon { width: 18px; height: 18px; }
.tkey-label { line-height: 1; }
/* The label a narrow key cannot fit whole ("⇧Tab") shrinks rather than
   overflowing its border. */
.tkey-row .tkey-label { overflow: hidden; text-overflow: clip; }
.tkey:active { background: var(--surface-3); transform: scale(.94); }
.tkey[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
/* Locked by a double tap: same colour, plus a ring to say it stays on. */
.tkey[data-lock="on"] { box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent); }

/* --------------------------------------------------------------- dialogs */

.modal, .key-sheet {
  padding: 20px; width: min(460px, 92vw);
  border: 1px solid var(--border-2); border-radius: var(--radius);
  background: var(--surface); color: var(--text);
  box-shadow: var(--shadow-md);
  animation: dialog-in var(--dur-slow) var(--ease);
}
.key-sheet { max-width: min(420px, 92vw); }
.modal::backdrop, .key-sheet::backdrop { background: rgba(12, 16, 22, .6); }
@keyframes dialog-in { from { opacity: 0; transform: translateY(10px) scale(.98); } }

.key-sheet-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(58px, 1fr));
  gap: 7px; margin-bottom: 14px;
}
.modal-actions { display: flex; gap: 9px; justify-content: flex-end; margin-top: 16px; }
.modal-error { color: var(--danger); font-size: 13px; }

.picker-roots { display: flex; gap: 7px; flex-wrap: wrap; }
.chip {
  padding: 5px 12px; font: inherit; font-size: 13px; font-weight: 500;
  border: 1px solid var(--border-2); border-radius: 999px;
  background: var(--surface-2); color: var(--text-soft); cursor: pointer;
  transition: background var(--dur-fast), color var(--dur-fast);
}
.chip:hover { background: var(--surface-3); color: var(--text); }
.picker-path { font-family: var(--mono); font-size: 12px; color: var(--text-faint); margin: 10px 0 5px; }
.picker-list {
  max-height: 220px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg);
}
.picker-item {
  display: block; width: 100%; text-align: left;
  padding: 7px 11px; font: inherit; font-family: var(--mono); font-size: 13px;
  border: 0; background: none; color: var(--text); cursor: pointer;
  transition: background var(--dur-fast);
}
.picker-item:hover { background: var(--surface-2); }

/* THE anti-zoom rule. iOS zooms whenever a focused field computes under 16px,
   and xterm's helper textarea inherits the terminal's font size — 13px on a
   phone. It is 0x0 and transparent, so this size is never seen; it exists only
   to stop the zoom. */
.xterm-helper-textarea { font-size: 16px !important; }

/* ----------------------------------------------------------------- phone */

@media (max-width: 820px) {
  .shell {
    /* One column, two rows: the top bar and everything else. */
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
    /* The visual viewport, not the layout viewport. When the iOS keyboard
       opens innerHeight does not change but visualViewport.height does, and
       this is the number that keeps the last terminal line above it. */
    height: var(--vvh);
  }

  .rail { display: none; }

  /* The rail is gone and the grid is one column wide, so main has to move into
     it. Left at column 2 it lands in an implicit second column instead, which
     pushes every page sideways off the screen. */
  .main { grid-column: 1; }

  /* Row one of the shell grid on a phone. In flow rather than fixed: the grid
     already reserves its height, so no page pads around it and nothing ends
     up hidden underneath it. */
  .topbar {
    grid-row: 1; grid-column: 1;
    display: flex; align-items: center; gap: 4px;
    height: calc(var(--topbar-h) + var(--safe-t));
    padding: 0 8px; padding-top: var(--safe-t);
    background: var(--surface); border-bottom: 1px solid var(--border);
  }
  .main { grid-row: 2; }

  /* Left end of the bar, where a thumb on a big phone actually reaches. */
  .topbar-menu > summary {
    display: flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; border-radius: var(--radius-sm);
    color: var(--text-soft); cursor: pointer; list-style: none;
    transition: background var(--dur-fast), color var(--dur-fast);
  }
  .topbar-menu > summary::-webkit-details-marker { display: none; }
  .topbar-menu > summary .icon { width: 22px; height: 22px; }
  .topbar-menu[open] > summary { background: var(--surface-3); color: var(--text); }
  /* Under the bar, not above it: this menu hangs from the top of the screen. */
  .topbar .nav-menu-list { top: 100%; bottom: auto; left: 0; margin: 6px 0 0; }
  .topbar-brand {
    font-size: 15px; font-weight: 650; letter-spacing: .2px; color: var(--accent);
  }
  .topbar-brand:hover { text-decoration: none; }

  /* With the keyboard up the bar is noise and the key bar needs the room.
     This is state, not size, which is why it is an attribute and not a query. */
  body[data-kb="open"] .topbar { display: none; }

  .pad { padding: 18px 14px 36px; }
  .page-title { font-size: 18px; margin-bottom: 14px; }
  .term-cwd { display: none; }
  .term-sessions > summary { max-width: 45vw; }
  .btn { min-height: 40px; }
}
