/* 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;
  --tabbar-h: 56px;
  --termbar-h: 46px;
  --keybar-h: 46px;
  --safe-b: env(safe-area-inset-bottom, 0px);
  /* The home-bar inset belongs to whichever bar is actually last on screen.
     On a phone that is the tab bar, so the key bar sitting above it must not
     claim the inset a second time — see the phone block. */
  --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;
}

.tabs { display: none; }

/* ------------------------------------------------------------------ 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; gap: 5px;
    height: calc(var(--keybar-h) + var(--kb-safe));
    padding: 5px 7px calc(5px + var(--kb-safe));
    overflow-x: auto; overflow-y: hidden;
    scrollbar-width: none;
    background: var(--surface); border-top: 1px solid var(--border);
    /* One horizontal swipe lane. Without this a drag along the bar scrolls the
       page and the button never fires. */
    touch-action: pan-x;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
  }
}
.term-keys::-webkit-scrollbar { display: none; }

.tkey {
  flex: 0 0 auto; min-width: 44px; height: 36px; padding: 0 10px;
  font-family: var(--mono); font-size: 14px; 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: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 {
    grid-template-columns: 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; }

  .tabs {
    display: flex; align-items: stretch;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
    height: calc(var(--tabbar-h) + var(--safe-b));
    padding-bottom: var(--safe-b);
    background: var(--surface); border-top: 1px solid var(--border);
    /* Rides up with the keyboard, exactly like the key bar. */
    transform: translateY(calc(-1 * var(--kb)));
  }
  .tabs .rail-item {
    flex: 1 1 0; flex-direction: column; gap: 3px; justify-content: center;
    font-size: 11px; border-radius: 0; background: none;
  }
  .tabs .rail-item[aria-current="page"] { background: none; color: var(--accent); }

  /* With the keyboard up the tab 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"] .tabs { display: none; }

  /* The tab bar is position:fixed, so every page — the terminal included —
     has to reserve its height or the bar covers the bottom of the content.
     For the terminal that bottom row is the key bar, which is exactly the
     part a phone cannot do without. */
  .main { padding-bottom: calc(var(--tabbar-h) + var(--safe-b)); }
  body[data-kb="open"] .main { padding-bottom: 0; }

  /* With the keyboard up the tab bar is gone, so the key bar is last on
     screen again and takes the inset back. */
  body { --kb-safe: 0px; }
  body[data-kb="open"] { --kb-safe: var(--safe-b); }

  .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; }
}
