/* Colour comes exclusively from custom properties. `theme::apply` overwrites
   them on <html> at runtime; the values here are the first theme in
   themes.toml, so the page is never unstyled while the wasm boots. */
:root {
  --bg: #1e1e2e;
  --bg-alt: #181825;
  --surface: #313244;
  --fg: #cdd6f4;
  --fg-dim: #a6adc8;
  --accent: #a6e3a1;
  --border: #45475a;
  --red: #f38ba8;
  --green: #a6e3a1;
  --yellow: #f9e2af;
  --blue: #89b4fa;
  --magenta: #cba6f7;
  --cyan: #94e2d5;
  --orange: #fab387;

  --font: "JetBrainsMono Nerd Font", ui-monospace, "SFMono-Regular", Menlo,
    Consolas, monospace;
  --line-height: 1.45;
  --status-height: 1.9rem;
}

@font-face {
  font-family: "JetBrainsMono Nerd Font";
  src: url("JetBrainsMonoNerdFontMono-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "JetBrainsMono Nerd Font";
  src: url("JetBrainsMonoNerdFontMono-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--fg);
}

body {
  font-family: var(--font);
  /* Small enough that a git graph fits on a phone, comfortable on a laptop. */
  font-size: clamp(12px, 0.55rem + 0.5vw, 15px);
  line-height: var(--line-height);
  -webkit-font-smoothing: antialiased;
}

.screen {
  min-height: 100dvh;
}

/* --- the deck ------------------------------------------------------------ */

/* One terminal, the size of the screen, that never moves. All the scrolling
   happens in an empty track behind it: the deck is one screen tall per window,
   and how far into it you have scrolled decides which window the frame shows.
   See scroll.rs. */

.deck {
  position: relative;
}

.stage {
  position: sticky;
  top: 0;
  height: calc(100dvh - var(--status-height));
  padding: clamp(0.5rem, 1.5vw, 1.25rem);
  display: flex;
}

/* Empty. Exists only to give the sticky frame something to travel through.
   The deck must end up at least `--windows` screens tall, or the last window
   is never selectable: the frame is a screen shorter than that (the status bar
   takes the difference), so the track has to make the shortfall back. The
   extra 2rem is slack for `dvh` and `innerHeight` disagreeing while a mobile
   browser's toolbar slides. */
.track {
  height: calc(
    (var(--windows, 1) - 1) * 100dvh + var(--status-height) + 2rem
  );
}

/* --- the terminal frame -------------------------------------------------- */

.terminal {
  flex: 1;
  display: flex;
  min-height: 0;
  border: 1px solid var(--border);
  background: var(--bg-alt);
  overflow: hidden;
}

/* --- windows and panes --------------------------------------------------- */

/* Every window stays mounted; only one is displayed. Between two of them the
   frame goes blank, because this is a single terminal being cleared and
   refilled rather than a stack of separate ones. */
.window {
  display: none;
  flex: 1;
  min-height: 0;
  gap: 0;
}

.window.visible {
  display: grid;
  animation: window-in 160ms ease-out;
}

@keyframes window-in {
  from {
    opacity: 0;
  }
}

.window[data-layout="single"] {
  grid-template-columns: 1fr;
}

.window[data-layout="split-h"] {
  grid-template-columns: 1fr 1fr;
}

.window[data-layout="split-v"] {
  grid-template-rows: 1fr 1fr;
}

.pane {
  padding: 0.7rem 0.9rem;
  min-width: 0;
  min-height: 0;
  /* The frame is fixed, so a window taller than the screen scrolls here.
     Reaching the end chains back to the page, which advances to the next
     window — no scroll handling of our own required. */
  overflow: auto;
}

/* --- scrollbars ---------------------------------------------------------- */

/* The default scrollbar is the one piece of chrome that ignores the theme, and
   it sits right against the terminal. Both syntaxes are needed: Firefox and
   recent Chrome honour `scrollbar-color`, older WebKit only the pseudo
   elements. Thin, square, no track — a scrollbar a terminal would have. */
html,
body,
.pane {
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}

html::-webkit-scrollbar,
body::-webkit-scrollbar,
.pane::-webkit-scrollbar {
  width: 0.7ch;
  height: 0.7ch;
}

html::-webkit-scrollbar-track,
body::-webkit-scrollbar-track,
.pane::-webkit-scrollbar-track,
html::-webkit-scrollbar-corner,
.pane::-webkit-scrollbar-corner {
  background: transparent;
}

html::-webkit-scrollbar-thumb,
body::-webkit-scrollbar-thumb,
.pane::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 0;
}

html::-webkit-scrollbar-thumb:hover,
body::-webkit-scrollbar-thumb:hover,
.pane::-webkit-scrollbar-thumb:hover {
  background: var(--accent);
}

/* The pane a command is writing into gets a brighter handle; the others stay
   quiet until you reach for them. */
.pane.focused {
  scrollbar-color: var(--fg-dim) transparent;
}

.pane.focused::-webkit-scrollbar-thumb {
  background: var(--fg-dim);
}

/* A split is the one place a rule carries information rather than decoration. */
.window[data-layout="split-h"] > .pane + .pane {
  border-left: 1px solid var(--border);
}

.window[data-layout="split-v"] > .pane + .pane {
  border-top: 1px solid var(--border);
}

/* The pane receiving output is the one tmux tints. */
.pane.focused {
  background: var(--bg);
}

.boot {
  color: var(--fg-dim);
}

.boot.error {
  color: var(--red);
  white-space: pre-wrap;
}

/* --- scrollback ---------------------------------------------------------- */

.block {
  margin-bottom: 1.2em;
}

.line {
  /* Preserve the exact column alignment commands emit; wrap only when a
     narrow screen leaves no choice. */
  white-space: pre-wrap;
  /* Blank lines must still occupy a row. */
  min-height: calc(1em * var(--line-height));
}

.prompt-line {
  display: flex;
  align-items: baseline;
  margin-bottom: 0.25em;
}

.prompt {
  white-space: pre;
  flex: none;
}

.cmd {
  white-space: pre-wrap;
  color: var(--fg);
}

/* --- live prompt --------------------------------------------------------- */

.prompt-input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  padding: 0;
  background: transparent;
  color: var(--fg);
  font: inherit;
  outline: none;
  caret-color: var(--accent);
}

/* --- status bar ---------------------------------------------------------- */

.statusbar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 10;
  display: flex;
  align-items: stretch;
  height: var(--status-height);
  background: var(--surface);
  color: var(--fg-dim);
  /* Never let a long window list push the clock off screen. */
  overflow: hidden;
}

.status-session,
.status-window,
.status-right {
  display: flex;
  align-items: center;
  gap: 0.4ch;
  padding: 0 0.9ch;
  white-space: nowrap;
}

.status-session {
  background: var(--accent);
  color: var(--bg);
  font-weight: 700;
  flex: none;
}

.status-windows {
  display: flex;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}

.status-windows::-webkit-scrollbar {
  display: none;
}

.status-window {
  border: 0;
  background: transparent;
  color: var(--fg-dim);
  font: inherit;
  cursor: pointer;
}

.status-window:hover {
  color: var(--fg);
  background: color-mix(in srgb, var(--accent) 15%, transparent);
}

/* tmux inverts the current window. */
.status-window.active {
  background: var(--accent);
  color: var(--bg);
  font-weight: 700;
}

.status-index {
  opacity: 0.7;
}

.status-right {
  margin-left: auto;
  flex: none;
  gap: 1.4ch;
}

.status-clock {
  color: var(--fg);
}

/* --- cursor -------------------------------------------------------------- */

.cursor {
  display: inline-block;
  width: 1ch;
  height: 1em;
  translate: 0 0.12em;
  background: var(--accent);
  animation: blink 1.06s steps(1) infinite;
}

@keyframes blink {
  50% {
    opacity: 0;
  }
}

/* --- colour roles, mirrored from commands::output::Color ----------------- */

.c-fg {
  color: var(--fg);
}
.c-dim {
  color: var(--fg-dim);
}
.c-accent {
  color: var(--accent);
}
.c-red {
  color: var(--red);
}
.c-green {
  color: var(--green);
}
.c-yellow {
  color: var(--yellow);
}
.c-blue {
  color: var(--blue);
}
.c-magenta {
  color: var(--magenta);
}
.c-cyan {
  color: var(--cyan);
}
.c-orange {
  color: var(--orange);
}

.b {
  font-weight: 700;
}

a {
  color: var(--blue);
  text-decoration-color: color-mix(in srgb, var(--blue) 40%, transparent);
  text-underline-offset: 0.2em;
}

a:hover {
  text-decoration-color: currentColor;
}

/* --- narrow screens ------------------------------------------------------ */

@media (max-width: 46rem) {
  /* One pane on a phone.

     Two half-height boxes was the worst of both worlds — about eighteen rows
     each, and a divider eating a row. Dropping the second pane instead would
     lose real content: the second `git show`, the second project of every
     pair, every banner. So the panes flow into one column and the *window*
     becomes the scroller rather than each pane. Pane routing is untouched;
     only the presentation collapses.

     `display: block`, not a one-column grid. A grid inside the frame has a
     definite height, so its auto rows get capped at that height and the panes
     — which must be `overflow: visible` for the window to do the scrolling —
     spilled straight over each other. In normal flow there are no rows to
     overflow. */
  .window.visible[data-layout="single"],
  .window.visible[data-layout="split-h"],
  .window.visible[data-layout="split-v"] {
    display: block;
    overflow: auto;
  }

  /* Every layout, not just the splits: with the pane scrolling in some windows
     and the window in others, "scroll down to leave" behaved differently from
     one window to the next. One scroller per window on a phone. */
  .window > .pane {
    overflow: visible;
  }

  /* No divider, and a rule between the two halves of one surface would read
     as a mistake rather than as information. */
  .window[data-layout="split-h"] > .pane + .pane,
  .window[data-layout="split-v"] > .pane + .pane {
    border-left: 0;
    border-top: 0;
    padding-top: 0;
  }

  /* Same reasoning for the focus tint. */
  .pane.focused {
    background: transparent;
  }

  .stage {
    padding: 0.4rem;
  }

  .pane {
    padding: 0.5rem 0.6rem;
  }

  /* The clock earns its space; the hostname does not. */
  .status-host {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cursor {
    animation: none;
  }
  * {
    scroll-behavior: auto !important;
  }
}
