/* =============================================================================
   The shell — status bar, scrollback, prompt, inline input, side panels
   Palette: the tone of the pane it lives in (see tokens.css). Charcoal canvas
   or orange canvas, every colour here is a role token, so the shell repaints
   itself when focus moves between the panes.
   ========================================================================== */

/* ----------------------------------------------------------------- statusbar */
.shell__bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 1.6ch;
  padding: 0.62em 1.1em;
  border-bottom: var(--hair) solid var(--pane-rule);
  font-size: 0.86em;
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
}

.shell__bar b {
  font-weight: 600;
  color: var(--accent);
  letter-spacing: 0.1em;
}

.shell__bar .spacer {
  margin-left: auto;
}

.shell__stat {
  color: var(--pane-dim);
}

.shell__stats {
  display: flex;
  align-items: baseline;
  gap: 1.6ch;
}

.shell__stat i {
  font-style: normal;
  color: var(--pane-fg);
}

.shell__stat--on i {
  color: var(--accent);
}

/* ------------------------------------------------------------------ viewport */
.shell__main {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
}

.shell__viewport {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  /* the prompt is the last line of this scroller, so the bottom pad belongs
     here rather than on the form */
  padding: 1.1em 1.15em 1em;
  scrollbar-width: thin;
  scrollbar-color: var(--ink-30) transparent;
}

.shell__viewport::-webkit-scrollbar {
  width: 9px;
}

.shell__viewport::-webkit-scrollbar-thumb {
  background: var(--ink-18);
}

.shell__scrollback {
  display: block;
}

/* --------------------------------------------------------------------- lines */
.line {
  display: block;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  margin: 0 0 0.08em;
  line-height: var(--shell-leading);
}

.line--gap {
  height: 0.72em;
}

.dim { color: var(--pane-dim); }
.faint { color: var(--pane-faint); }
.hot { color: var(--accent); }
.hot-dim { color: var(--accent-dim); }
.ink { color: var(--pane-fg); }
.bright { color: var(--ink); }
.underlined { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; }
.strike { text-decoration: line-through; opacity: 0.6; }
.b { font-weight: 600; }

/* emphasis stays inside the loaded weight range, so the browser never reaches
   for a synthesised or unloaded bold */
b, strong { font-weight: 600; }

/* syntax classes emitted by the highlighter */
.tok-cmd { color: var(--accent); font-weight: 500; }
.tok-flag { color: var(--ink-80); }
.tok-arg { color: var(--ink-60); }
.tok-str { color: var(--ink); }
.tok-path { color: var(--accent-bright); }
.tok-key { color: var(--accent); font-weight: 600; }
.tok-punct { color: var(--pane-faint); }
.tok-num { color: var(--ink-80); }
.tok-err { color: var(--accent); text-decoration: underline wavy var(--accent-dim); text-underline-offset: 3px; }

/* -------------------------------------------------------------------- prompt */
.prompt {
  color: var(--accent);
  white-space: pre;
  line-height: var(--shell-leading);
}

.prompt .user { color: var(--accent); font-weight: 600; }
.prompt .host { color: var(--accent-dim); }
.prompt .path { color: var(--accent-bright); }
.prompt .sigil { color: var(--accent); font-weight: 600; }

.prompt--ro .user { font-weight: 500; }

/* echo of the executed command inside the scrollback */
.line--cmd .cmd {
  color: var(--pane-fg);
}

/* ------------------------------------------------------------------ listings */
.ls {
  display: grid;
  grid-template-columns: max-content max-content max-content 1fr;
  column-gap: 1.4ch;
  white-space: pre;
}

.ls--long {
  grid-template-columns: max-content max-content max-content max-content max-content max-content 1fr;
}

.ls__name {
  color: var(--accent);
  cursor: pointer;
}

.ls__name--dir { font-weight: 600; }
.ls__name--file { color: var(--ink-80); }
.ls__name:hover,
.ls__name:focus-visible {
  background: var(--accent);
  color: var(--on-accent);
  outline: none;
}

/* ---------------------------------------------------------- project / news */
.entry {
  display: block;
  border-left: var(--hair) solid var(--pane-rule);
  padding: 0.15em 0 0.15em 1.1em;
  margin: 0.35em 0 0.9em;
}

.entry__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 2ch;
}

.entry__kind {
  color: var(--pane-faint);
  font-size: 0.86em;
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
}

.entry__title {
  color: var(--pane-fg);
  font-weight: 600;
}

.entry__body {
  color: var(--pane-dim);
  max-width: 74ch;
}

.entry__thumb {
  display: block;
  width: min(100%, 400px);
  aspect-ratio: 4 / 3;
  margin-top: 0.5em;
  border: var(--hair) solid var(--pane-rule);
  object-fit: cover;
}

.entry__foot {
  display: flex;
  align-items: baseline;
  gap: 2ch;
  margin-top: 0.45em;
}

.act {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--accent);
  cursor: pointer;
}

.act:hover,
.act:focus-visible {
  background: var(--accent);
  color: var(--on-accent);
  outline: none;
}

/* man pages: a manual entry laid out as a block — a head, then spaced
   sections, each an uppercase title over an indented body. Every row keeps the
   one shell line-height, so nothing in here breaks the rhythm of the console. */
.man {
  display: block;
  border-left: var(--hair) solid var(--pane-rule);
  padding: 0.15em 0 0.15em 1.1em;
  margin: 0.35em 0 0.9em;
  line-height: var(--shell-leading);
}

.man__head {
  display: flex;
  align-items: baseline;
  gap: 2ch;
  margin-bottom: 0.2em;
}

.man__name {
  color: var(--accent);
  font-weight: 600;
}

.man__sum { color: var(--pane-dim); }

.man__section { margin-top: 0.75em; }

.man__title {
  color: var(--pane-faint);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  line-height: var(--shell-leading);
}

.man__body {
  margin: 0.2em 0 0 2ch;
  line-height: var(--shell-leading);
}

.man__row {
  display: block;
  color: var(--pane-fg);
  line-height: var(--shell-leading);
}

.man__ex { color: var(--ink-60); }

.man__grid {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 3ch;
  row-gap: 0.15em;
  margin: 0.2em 0 0 2ch;
  line-height: var(--shell-leading);
}

.man__key {
  color: var(--accent);
  font-weight: 500;
}

.man__val { color: var(--pane-fg); }
.man__see { color: var(--ink-60); }

/* key/value listings (man -k, `man` with no argument) share the grid, indented
   under their group label and spaced so groups do not run together */
.man__sections {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 3ch;
  row-gap: 0.15em;
  margin: 0.15em 0 0.5em 2ch;
  line-height: var(--shell-leading);
}

/* ------------------------------------------------------------------- top cmd */
.top {
  display: grid;
  grid-template-columns: max-content max-content 1fr;
  column-gap: 2.4ch;
  row-gap: 0.1em;
  border-left: var(--hair) solid var(--pane-rule);
  padding-left: 1.1em;
  margin: 0.3em 0 0.9em;
}

.top__k { color: var(--pane-faint); }
.top__v { color: var(--pane-fg); }
.top__v i { font-style: normal; color: var(--accent); }

/* ----------------------------------------------------------------- hexdump */
.hexdump {
  display: block;
  white-space: pre;
  color: var(--pane-fg);
  margin: 0.25em 0 0.5em;
  overflow-x: auto;
}

.hexdump__line { display: block; }

.meter {
  display: inline-block;
  color: var(--accent-dim);
  letter-spacing: -0.06em;
}

/* ------------------------------------------------------------------ chat/od */
/* The chat lives in the left panel now; only its parts remain here. */
.pane__body {
  overflow-y: auto;
  padding: 0.9em 1em;
  scrollbar-width: thin;
  scrollbar-color: var(--ink-30) transparent;
}

.pane__body::-webkit-scrollbar { width: 8px; }
.pane__body::-webkit-scrollbar-thumb { background: var(--ink-18); }

.msg {
  display: block;
  margin-bottom: 0.25em;
  overflow-wrap: anywhere;
}

.msg__t { color: var(--pane-faint); }
.msg__nick,
.msg__nick--self {
  color: hsl(var(--user-hue, 30), var(--nick-sat, 85%), var(--nick-light, 70%));
  font-weight: 600;
}
.msg__text {
  color: hsl(var(--user-hue, 30), var(--msg-sat, 55%), var(--msg-light, 82%));
  font-weight: 400;
}
.msg--system { color: var(--pane-dim); }

.pane__form {
  display: flex;
  align-items: baseline;
  gap: 0.6ch;
  border-top: var(--hair) solid var(--pane-rule);
  padding: 0.55em 1em;
}

/* ------------------------------------------------------------------- input */
/* The prompt is the last line of the terminal content: no border, no box, no
   padding of its own, because it is a line inside the viewport's scroller and
   sits right after whatever the shell last printed. */
.shell__form {
  position: relative;
  display: flex;
  /* The prompt string carries its own trailing space, and both sides share one
     line-height, so the live line is laid out exactly like the echoed line. No
     flex gap and no baseline alignment: an empty mirror has no line box to take
     a baseline from, which is what used to make the line jump on the first
     keystroke. */
  align-items: stretch;
  gap: 0;
  padding: 0;
}

.shell__form[data-locked="true"] {
  opacity: 0.55;
  pointer-events: none;
}

.field {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  line-height: var(--shell-leading);
}

/* the mirror renders syntax colouring; the real input sits on top, invisible */
.field__mirror,
.shell__form .field__input {
  font: inherit;
  line-height: var(--shell-leading);
  letter-spacing: normal;
  padding: 0;
  margin: 0;
  border: 0;
  white-space: pre;
  overflow: hidden;
}

.field__mirror {
  display: block;
  color: var(--pane-fg);
  min-height: calc(1em * var(--shell-leading));
}

.field__ghost {
  color: var(--ink-18);
}

/* while a secret is being asked for, the mirror shows only the mask */
.field__secret {
  color: var(--pane-fg);
}

.shell__form .field__input {
  position: absolute;
  inset: 0;
  width: 100%;
  background: transparent;
  color: transparent;
  /* the native caret is a thin line and cannot be styled into a block, so the
     block is drawn below and the native one is simply not shown */
  caret-color: transparent;
  outline: none;
  appearance: none;
}

.shell__form .field__input::placeholder {
  color: var(--ink-18);
}

/* the room input inside the chat view is a real, visible field */
.chat__input,
.chat__input:focus,
.chat__input:focus-visible,
.chat__input:active {
  flex: 1 1 auto;
  min-width: 0;
  background: transparent !important;
  border: 0 !important;
  border-style: none !important;
  outline: 0 !important;
  outline-style: none !important;
  box-shadow: none !important;
  color: var(--brand-ink, var(--pane-fg)) !important;
  caret-color: var(--accent);
  font: inherit;
  appearance: none;
  -webkit-appearance: none;
}

.chat__input::placeholder {
  color: var(--pane-faint);
}

/* The one cursor: a blinking block, one character cell wide, sitting exactly
   where the caret is. The native line caret is hidden with caret-color above,
   so there is never a second one. */
.caret {
  position: absolute;
  top: 0;
  left: 0;
  width: 1ch;
  height: calc(1em * var(--shell-leading));
  background: var(--accent);
  pointer-events: none;
  animation: blink 1.05s steps(1, end) infinite;
}

@keyframes blink {
  0%, 50% { opacity: 1; }
  50.01%, 100% { opacity: 0; }
}

/* ----------------------------------------------------------------- boot log */
/* the pubkey handshake is "communicated by scroll-through" before the shell
   becomes visible to the user, and stops at the blinking input prompt. */
.boot {
  position: absolute;
  inset: 0;
  z-index: 4;
  overflow: hidden;
  padding: 1.1em 1.15em;
  background: var(--pane-bg);
  color: var(--pane-dim);
}

.boot[hidden] { display: none; }

.boot__curtain {
  position: absolute;
  left: 0;
  right: 0;
  height: 62%;
  backdrop-filter: blur(1.1px);
  pointer-events: none;
}

.boot__curtain--top {
  top: 0;
  background: linear-gradient(to bottom, var(--pane-bg) 4%, transparent);
}

.boot[data-stage="done"] .boot__curtain {
  display: none;
}

.boot__scroll {
  display: block;
}

.lock {
  color: var(--accent-dim);
}

.lock--ok { color: var(--accent); }
.lock--key { color: var(--ink-80); overflow-wrap: anywhere; }

/* --------------------------------------------------------------------- pane */
.roster {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6ch;
  margin-bottom: 0.9em;
}

.chip {
  border: var(--hair) solid var(--pane-rule);
  padding: 0.05em 0.6em;
  color: var(--ink-80);
}

.chip--self {
  border-color: var(--accent-dim);
  color: var(--accent);
}

.pane__note { margin-bottom: 0.9em; }

.pane__log {
  border-top: var(--hair) solid var(--pane-rule);
  padding-top: 0.7em;
}

.pane__log .msg { margin-bottom: 0.05em; }
.pane__log .msg .line { margin: 0; }

/* ---------------------------------------------------------------------- vim */
.vim {
  position: absolute;
  inset: 0;
  z-index: 6;
  display: flex;
  flex-direction: column;
  background: var(--pane-bg);
  outline: none;
}

.vim__title {
  padding: 0.4em 1.15em;
  border-bottom: var(--hair) solid var(--pane-rule);
  font-size: 0.86em;
}

.vim__body {
  flex: 1 1 auto;
  overflow: hidden;
  padding: 0.7em 1.15em;
}

.vim__line {
  white-space: pre;
  line-height: var(--shell-leading);
  overflow-wrap: normal;
}

.vim__cursor {
  background: var(--accent);
  color: var(--on-accent);
}

.vim__cursor--ins {
  background: transparent;
  color: var(--pane-fg);
  box-shadow: inset 2px 0 0 var(--accent);
}

.vim__cmd {
  min-height: 1.5em;
  padding: 0 1.15em;
  color: var(--pane-fg);
}

.vim__status {
  display: flex;
  gap: 1.6ch;
  padding: 0.4em 1.15em;
  border-top: var(--hair) solid var(--pane-rule);
  background: var(--ink-10);
  font-size: 0.86em;
}

.vim__status .spacer { margin-left: auto; }

/* ----------------------------------------------------------------- a11y ---- */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

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