/* manygit — landing page
 *
 * Palette note: manygit never paints a background. It colors only the "chrome"
 * (accent / group / dim / error) and inherits everything else from your
 * terminal — see internal/tui/theme.go. This page does the same: the ground
 * stays near-black in every theme, and only the four chrome variables swap.
 * Every hex below marked REAL is copied verbatim from themeList in theme.go.
 */

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

:root {
  /* ground — "your terminal", not a theme value */
  --bg: #0b0b0c;
  --surface: #101012;
  --ink: #d1d0c5; /* serika's text; a neutral terminal foreground */

  /* chrome — swapped per theme, values REAL from theme.go. --dim is a terminal
     *chrome* colour (borders, inactive tabs, the TUI's own dim text); it is not
     a prose colour and several themes put it under 4.5:1 on this ground. */
  --accent: #e2b714;
  --group: #e2b714;
  --dim: #646669;
  --error: #ca4754;

  /* --muted is the page's secondary *reading* colour: the same intent as --dim
     but lifted to clear WCAG AA (4.5:1) on --bg at the 11-13px this page sets.
     theme.go's #646669 measures 3.42:1 and its "default" #585858 only 2.77:1. */
  --muted: #838588;

  /* status column — deliberately NOT themed, mirroring theme.go's comment:
     "semantic status colors are intentionally NOT themed so they stay
     readable across themes". Red is the exception: theme.go paints errors from
     t.Error, so `.rd` follows --error rather than a fixed status colour. */
  --c-green: #5ec269;
  --c-yellow: #d7ba4a;
  --c-cyan: #4fb8c9;
  --c-magenta: #b47ee5;
  --c-orange: #f0883e;

  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --display: "Doto", var(--mono);

  --rule: color-mix(in srgb, var(--dim) 34%, transparent);
  --lane: 148px; /* the right-aligned label column */
  --gap: 40px;
  --measure: 1180px;

  --t: 220ms cubic-bezier(0.2, 0, 0, 1);
}

/* Each block: --dim/--accent/--group/--error are theme.go's values verbatim;
   --muted is that theme's --dim lifted to >=4.5:1 on --bg (measured, not eyeballed).
   nord / catppuccin / 8008 already clear AA, so their --muted is their own --dim. */
:root[data-theme="default"] {
  --accent: #00afff;
  --group: #4a9eff;
  --dim: #585858; /* 2.77:1 */
  --muted: #7c7c7c; /* 4.71:1 */
  --error: #cd3131;
}
:root[data-theme="serika_dark"] {
  --accent: #e2b714;
  --group: #e2b714;
  --dim: #646669; /* 3.42:1 */
  --muted: #838588; /* 5.32:1 */
  --error: #ca4754;
}
:root[data-theme="dracula"] {
  --accent: #bd93f9;
  --group: #bd93f9;
  --dim: #6272a4; /* 4.18:1 */
  --muted: #7a88b4; /* 5.63:1 */
  --error: #ff5555;
}
:root[data-theme="nord"] {
  --accent: #88c0d0;
  --group: #88c0d0;
  --dim: #929aaa;
  --muted: #929aaa; /* 6.96:1 */
  --error: #bf616a;
}
:root[data-theme="catppuccin"] {
  --accent: #cba6f7;
  --group: #cba6f7;
  --dim: #7f849c;
  --muted: #8891a6; /* 6.23:1 */
  --error: #f38ba8;
}
:root[data-theme="8008"] {
  --accent: #f44c7f;
  --group: #f44c7f;
  --dim: #939eae;
  --muted: #939eae; /* 7.25:1 */
  --error: #da3333;
}

/* ------------------------------------------------------------ light mode -- */

/* manygit never paints a background — it colors the chrome and takes the ground
   from your terminal (theme.go). So this isn't a reskin of the tool: it is the
   tool in a light terminal, which is what you get if that's what you run.
   `data-mode` (the ground) and `data-theme` (the chrome) are separate axes and
   compose: six themes x two grounds.

   theme.go's palettes are tuned for a dark terminal and none of their accents
   clear 4.5:1 on paper, so each is darkened here — same hue and saturation,
   lower lightness, measured rather than guessed. serika's #e2b714 becomes a dark
   gold because a yellow cannot be both vivid and dark; that's the honest cost. */
:root[data-mode="light"] {
  --bg: #eeede8;
  --surface: #e6e5df;
  --ink: #2b2d30; /* 11.78:1 */

  /* status column, darkened for paper — still unthemed, still fixed */
  --c-green: #2e7936; /* 4.59:1 */
  --c-yellow: #7d691c; /* 4.58:1 */
  --c-cyan: #277481; /* 4.59:1 */
  --c-magenta: #9040d8; /* 4.58:1 */
  --c-orange: #ae500e; /* 4.53:1 */
}

:root[data-mode="light"][data-theme="default"] {
  --accent: #0072a6; /* 4.53:1 */
  --group: #0066dc; /* 4.55:1 */
  --dim: #585858; /* 6.07:1 */
  --muted: #585858;
  --error: #c93030; /* 4.54:1 */
}
:root[data-mode="light"][data-theme="serika_dark"] {
  --accent: #81680b; /* 4.57:1 */
  --group: #81680b;
  --dim: #646669; /* 4.91:1 */
  --muted: #646669;
  --error: #c33846; /* 4.51:1 */
}
:root[data-mode="light"][data-theme="dracula"] {
  --accent: #8639f4; /* 4.59:1 */
  --group: #8639f4;
  --dim: #6272a4; /* 4.01:1 — chrome only */
  --muted: #5a6a9c; /* 4.51:1 */
  --error: #d60000; /* 4.64:1 */
}
:root[data-mode="light"][data-theme="nord"] {
  --accent: #357385; /* 4.54:1 */
  --group: #357385;
  --dim: #7e889b; /* 3.05:1 — chrome only */
  --muted: #626c7e; /* 4.52:1 */
  --error: #b24852; /* 4.54:1 */
}
:root[data-mode="light"][data-theme="catppuccin"] {
  --accent: #8b38ed; /* 4.61:1 */
  --group: #8b38ed;
  --dim: #7f849c; /* 3.15:1 — chrome only */
  --muted: #656a83; /* 4.54:1 */
  --error: #d01549; /* 4.61:1 */
}
:root[data-mode="light"][data-theme="8008"] {
  --accent: #d30d49; /* 4.57:1 */
  --group: #d30d49;
  --dim: #7b899c; /* 3.04:1 — chrome only */
  --muted: #5f6c7f; /* 4.55:1 */
  --error: #cf2626; /* 4.53:1 */
}

/* ------------------------------------------------------------- baseline -- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.62;
  font-weight: 400;
  letter-spacing: 0.01em;
  -webkit-font-smoothing: antialiased;
  transition: color var(--t);
}

/* The underline tracks the link's own colour rather than the (much fainter)
   --rule, so inline links in --muted footer text stay distinguishable. */
a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, currentColor 55%, transparent);
  transition: border-color var(--t), color var(--t);
}
a:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

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

::selection {
  background: var(--accent);
  color: var(--bg);
}

.shell {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 0 28px;
}

/* visually hidden, still announced */
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: 12px;
  top: 12px;
  z-index: 99;
  background: var(--accent);
  color: var(--bg);
  padding: 8px 14px;
  border: 0;
}

/* -- shared atoms ---------------------------------------------------------- */

/* [ chip ] — manygit renders its own panel titles as "[1] Repos"; the bracket
   is the product's structural device, not decoration. */
.chip {
  display: inline-flex;
  gap: 0.5em;
  align-items: center;
  color: var(--muted);
  font-size: 11px;
  letter-spacing: 0.08em;
  white-space: nowrap;
  transition: color var(--t);
}
.chip::before {
  content: "[";
  color: var(--muted);
}
.chip::after {
  content: "]";
  color: var(--muted);
}
a.chip {
  border-bottom: 0;
}
a.chip:hover {
  color: var(--accent);
}

/* the ground toggle wears the same bracket as everything else in the masthead */
.chip--btn {
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.08em;
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
}
.chip--btn:hover {
  color: var(--accent);
}

/* The mark is manygit's own layout at 24x15: one tall pane on the left (Repos,
   the one you act on, so it carries the accent) against the stacked right column
   (Branches/PRs over Graph/Changes/Output). Same shape as .term__body below and
   as the favicon. It follows the theme because the real panes do. */
.bar {
  width: 24px;
  height: 15px;
  flex: none;
  display: grid;
  grid-template-columns: 9px 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 2px;
}
.bar i {
  background: var(--dim);
  border-radius: 1px;
  transition: background var(--t);
}
.bar i:first-child {
  grid-row: 1 / 3;
  background: var(--accent);
}

/* -------------------------------------------------------------- masthead -- */

/* Opaque, not frosted: --bg never changes between themes, so a blur would cost a
   compositor layer to tint one flat colour with another. The hairline rule is
   what separates the header from the page. */
.masthead {
  border-bottom: 1px solid var(--rule);
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--bg);
}

.masthead__in {
  display: flex;
  align-items: center;
  gap: 16px;
  height: 56px;
}

.wordmark {
  display: flex;
  align-items: center;
  gap: 12px;
  border-bottom: 0;
  margin-right: auto;
}
.wordmark__txt {
  font-family: var(--display);
  font-size: 21px;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
}

/* ------------------------------------------------------------------ hero -- */

/* Budgeted so the masthead, the hero and the whole terminal fit one 900px-tall
   viewport: the demo is the thesis and shouldn't need a scroll to be found. */
.hero {
  padding: clamp(34px, 5vw, 62px) 0 clamp(18px, 2.5vw, 28px);
}

.hero__grid {
  display: grid;
  grid-template-columns: var(--lane) minmax(0, 1fr);
  gap: var(--gap);
}

/* The right-aligned label column, lifted from the brief's first reference: the
   labels ARE the manual's sections, so they're h2s here, not decoration. */
.lane {
  margin: 0;
  text-align: right;
  color: var(--muted);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.12em;
  line-height: 1.62;
  padding-top: 0.5em;
  transition: color var(--t);
}

.hero h1 {
  margin: 0;
  font-size: clamp(26px, 3.4vw, 41px);
  line-height: 1.12;
  font-weight: 600;
  letter-spacing: -0.025em;
  max-width: 21ch;
}
.hero h1 em {
  font-style: normal;
  color: var(--accent);
  transition: color var(--t);
}

.hero__sub {
  margin: 20px 0 0;
  max-width: 64ch;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.7;
  transition: color var(--t);
}
.hero__sub strong {
  color: var(--ink);
  font-weight: 500;
}
.hero__sub code {
  color: var(--ink);
  font-size: 0.94em;
  white-space: nowrap;
}

.hero__cta {
  margin-top: 24px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 22px;
  align-items: center;
}

/* -- copyable command ------------------------------------------------------ */

/* fit-content so the copy button sits against the command, not stranded at the
   far edge of the column */
.cmd {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--rule);
  border-radius: 5px;
  background: var(--surface);
  overflow: hidden;
  width: fit-content;
  max-width: 100%;
  transition: border-color var(--t);
}
.cmd:hover {
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
}

.cmd__txt {
  padding: 11px 14px;
  overflow-x: auto;
  white-space: nowrap;
  font-size: 12.5px;
  scrollbar-width: none;
}
.cmd__txt::-webkit-scrollbar {
  display: none;
}
.cmd__sigil {
  color: var(--accent);
  user-select: none;
  margin-right: 0.75em;
  transition: color var(--t);
}
/* a real shell comment, so the annotation can't be mistaken for the command */
.cmd__note {
  color: var(--muted);
  user-select: none;
  transition: color var(--t);
}

.cmd__copy {
  flex: none;
  border: 0;
  border-left: 1px solid var(--rule);
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.08em;
  padding: 0 16px;
  cursor: pointer;
  transition: color var(--t), background var(--t);
}
.cmd__copy:hover {
  color: var(--bg);
  background: var(--accent);
}
.cmd__copy[data-copied="1"] {
  color: var(--bg);
  background: var(--c-green);
}

/* ------------------------------------------------------------------ demo -- */

.demo {
  padding: 0 0 clamp(48px, 7vw, 84px);
}

.demo__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 12px;
  color: var(--muted);
  font-size: 11.5px;
  transition: color var(--t);
}

.demo__scroll {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  border-radius: 8px;
}

/* A TUI has no keyboard on a phone and doesn't reflow, so the cue changes:
   swipe the grid, drive it from the keypad. */
.demo__cue--tap {
  display: none;
}
@media (hover: none), (max-width: 720px) {
  .demo__cue--key {
    display: none;
  }
  .demo__cue--tap {
    display: inline-flex;
  }
}

/* the terminal itself. Fixed min-width so the pane grid keeps its proportions;
   narrow screens swipe rather than reflow (a TUI doesn't reflow either). */
.term {
  min-width: 720px;
  /* 2.0:1 rather than the 2.5:1 this started at — the real tool runs nearer
     1.6:1, and at 448px the Repos pane couldn't show all 12 repos at once,
     which is the whole point of the thing. */
  height: 560px;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  border: 1px solid var(--rule);
  border-radius: 8px;
  padding: 14px 16px 14px;
  font-size: 12px;
  line-height: 1.5;
  position: relative;
  cursor: text;
  transition: border-color var(--t), box-shadow var(--t);
}
#screen {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
/* A ring, not a bloom: .demo__scroll's overflow-x makes overflow-y `auto` too, so
   it clips on all four sides and any glow would render half-cropped. */
.term:focus {
  outline: 0;
  border-color: color-mix(in srgb, var(--accent) 62%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 24%, transparent);
}

/* Click-to-focus veil. The blur is the affordance: it reads as "this is behind
   glass, wake it up" and pushes the eye to the cue chip. Deliberately soft —
   enough to defocus, not so much that you can't tell it's a terminal. It clears
   the moment the pane takes focus, so the text is never blurred while readable
   content is expected of it (keyboard users reach it by Tab, same as a click). */
.term__veil {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: grid;
  place-items: center;
  border-radius: 8px;
  background: color-mix(in srgb, var(--bg) 12%, transparent);
  backdrop-filter: blur(1.3px);
  -webkit-backdrop-filter: blur(1.3px);
  transition: opacity var(--t);
}
.term:focus .term__veil {
  opacity: 0;
  pointer-events: none;
}
.term__veil span {
  border: 1px solid var(--accent);
  color: var(--accent);
  background: var(--bg);
  padding: 9px 18px;
  border-radius: 4px;
  font-size: 12px;
  letter-spacing: 0.06em;
  transition: color var(--t), border-color var(--t);
}

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

.term__top {
  display: flex;
  gap: 12px;
  align-items: baseline;
  flex: none;
  white-space: nowrap;
}
.term__brand {
  color: var(--accent);
  font-weight: 700;
  flex: none;
  transition: color var(--t);
}
.term__news {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
}
.term__badge {
  flex: none;
}

.term__body {
  display: grid;
  grid-template-columns: 38fr 62fr;
  gap: 8px;
  margin-top: 1.5em;
  flex: 1;
  min-height: 0;
}
/* helpView / graphView / newsView are the whole screen — no bars above them, so
   the pane title's -0.72em lift is absorbed by .term's own 14px padding-top. */
.term__body--one {
  grid-template-columns: minmax(0, 1fr);
  margin-top: 0;
}
/* zoomedView is different: it keeps the brand bar above the pane, so the title
   still needs its clearance or it lands on top of the bar. */
.term__body--zoom {
  grid-template-columns: minmax(0, 1fr);
}
.term__col {
  display: grid;
  gap: 8px;
  min-width: 0;
}
/* Repos over Scripts; Branches/PRs over Graph/Changes/Output.
   Ratios mirror view.go: top slot = 40% of the right column. */
/* Scripts is sized to its content, not given a fixed slot: view.go sets
   scriptsInner = len(m.scripts) (clamped to [3, bodyH/3]), so 4 scripts = 4 rows.
   4*18 line-height + 14 padding + 2 border = 88. Everything left goes to Repos. */
.term__col--l {
  grid-template-rows: 1fr 88px;
}
.term__col--r {
  grid-template-rows: 40fr 60fr;
}

/* 18px, matching .term__body's own top margin: the footer line was sitting hard
   against the Scripts/Output bottom borders. Same breathing room top and bottom. */
.term__bot {
  display: flex;
  gap: 12px;
  align-items: baseline;
  margin-top: 18px;
  flex: none;
  white-space: nowrap;
}
.term__status {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
}
.term__ind {
  flex: none;
  display: flex;
  gap: 18px;
}

/* -- pane ------------------------------------------------------------------ */

/* overflow must stay visible: the title sits at a negative offset so it splices
   into the top border, the way lipgloss draws ╭─[1] Repos───╮. The body clips
   its own content instead. */
.pane {
  position: relative;
  border: 1px solid var(--dim);
  border-radius: 6px;
  padding: 7px 9px;
  min-width: 0;
  overflow: visible;
  transition: border-color var(--t);
}
.pane[data-focused="1"] {
  border-color: var(--accent);
}

/* the title spliced into the top border, like lipgloss's ╭─[1] Repos───╮ */
/* `right: auto` so the label is only as wide as its text: it must knock a hole in
   the top border exactly the width of the title and no further, the way lipgloss
   splices it — ╭─[1] Repos──────╮. A full-width box here would paint --bg over
   the whole border and leave the pane looking open on top. */
.pane__title {
  position: absolute;
  top: -0.72em;
  left: 9px;
  right: auto;
  max-width: calc(100% - 20px);
  padding: 0 5px;
  background: var(--bg);
  font-size: 11px;
  line-height: 1.4;
  color: var(--dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: clip;
  transition: color var(--t);
}
.pane[data-focused="1"] .pane__title {
  color: var(--accent);
}

.pane__body {
  height: 100%;
  overflow: hidden;
  white-space: pre;
  tab-size: 4; /* Go diffs are tab-indented; 8 would push the hunk off the pane */
}

/* tab bar inside a pane title */
.tab {
  padding: 0 0.5em;
}
.tab[data-on="1"] {
  background: var(--ink);
  color: var(--bg);
  font-weight: 700;
}
.tab[data-on="0"] {
  color: var(--dim);
}
.tabdiv {
  color: var(--dim);
}
.tabhint {
  color: var(--dim);
  padding-left: 1.5em;
  font-weight: 400;
}

/* -- repo row: fixed cells, exactly like computeDims's column budget -------- */

.row {
  display: flex;
  gap: 0;
  white-space: pre;
}
.row__cur {
  flex: none;
  width: 4ch;
}
.row__name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.row__dirty {
  flex: none;
  width: 5ch;
  padding-left: 1ch;
}
.row__st {
  flex: none;
  width: 10ch;
  padding-left: 1ch;
}
.row[data-on="1"] .row__name {
  color: var(--accent);
  font-weight: 700;
}
.row[data-mark="1"] .row__cur {
  color: var(--dim);
}
.row[data-on="1"] .row__cur {
  color: var(--accent);
  font-weight: 700;
}

/* centered empty states — renderPRsView / renderOutputView / renderChangesView
   all call centerBlock() for these */
.center {
  height: 100%;
  display: grid;
  place-content: center;
  text-align: center;
  color: var(--dim);
  gap: 0.9em;
  white-space: normal;
  padding: 0 8%;
}

/* -- ansi-ish text classes ------------------------------------------------- */

.d {
  color: var(--dim);
}
.a {
  color: var(--accent);
}
.gp {
  color: var(--group);
  font-weight: 700;
}
.gr {
  color: var(--c-green);
}
.yl {
  color: var(--c-yellow);
}
.cy {
  color: var(--c-cyan);
}
.mg {
  color: var(--c-magenta);
}
.og {
  color: var(--c-orange);
}
.rd {
  color: var(--error);
}
/* The @handles in the PRs pane link to real GitHub profiles. It must be
   indistinguishable from the .gp text around it, so both of the base `a` rules
   are undone here: the border-bottom underline, and the accent colour swap on
   hover. The pointer cursor is the entire affordance — you find it by aiming at
   it. Underline appears only once you're already hovering, to confirm the hit. */
.pane__body a.gh {
  border-bottom: 1px solid transparent;
  cursor: pointer;
}
.pane__body a.gh:hover,
.pane__body a.gh:focus-visible {
  color: var(--group);
  border-bottom-color: currentColor;
}

.cur {
  color: var(--accent);
  font-weight: 700;
}
.rev {
  background: var(--ink);
  color: var(--bg);
  font-weight: 700;
}

/* ---------------------------------------------------------------- keypad -- */

.keypad {
  margin-top: 14px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}
.keypad__lbl {
  color: var(--muted);
  font-size: 11px;
  margin-right: 6px;
  transition: color var(--t);
}

.key {
  font: inherit;
  font-size: 11.5px;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: 3px 9px;
  cursor: pointer;
  transition: color var(--t), border-color var(--t), background var(--t);
}
.key:hover {
  color: var(--accent);
  border-color: var(--accent);
}
.key:active {
  background: var(--accent);
  color: var(--bg);
}
.key em {
  font-style: normal;
  color: var(--ink);
}
.key:hover em {
  color: inherit;
}

/* ----------------------------------------------------------------- manual -- */

.manual {
  border-top: 1px solid var(--rule);
}

.sec {
  display: grid;
  grid-template-columns: var(--lane) minmax(0, 1fr);
  gap: var(--gap);
  padding: clamp(38px, 5vw, 60px) 0;
  border-bottom: 1px solid var(--rule);
  /* clears the 56px sticky masthead when jumped to via #install / #keys / … */
  scroll-margin-top: 72px;
}
.sec:last-child {
  border-bottom: 0;
}

/* Spacing owns the direct children and nothing else re-declares margin, so the
   flow rule can't be out-specified by a later element-qualified selector. */
.sec__body > * {
  margin: 0;
}
.sec__body > * + * {
  margin-top: 18px;
}

.sec__body p {
  max-width: 68ch;
  color: var(--muted);
  line-height: 1.72;
  transition: color var(--t);
}
.sec__body p strong {
  color: var(--ink);
  font-weight: 500;
}
.sec__body code {
  color: var(--ink);
  font-size: 0.94em;
  white-space: nowrap;
}
.sec__body h3 {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: 0.01em;
}
/* qualified with p so it outranks `.sec__body p` without reaching for !important */
.sec__body p.sec__lede {
  color: var(--ink);
  font-size: 15px;
  line-height: 1.6;
  max-width: 46ch;
  letter-spacing: -0.01em;
}
/* a heading introduces what follows — tighten it toward its own block */
.sec__body > h3 + * {
  margin-top: 10px;
}
.sec__body > * + h3 {
  margin-top: 30px;
}

/* -- key table ------------------------------------------------------------- */

.kt {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}
.kt th {
  text-align: left;
  font-weight: 400;
  color: var(--muted);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  padding: 0 0 8px;
  border-bottom: 1px solid var(--rule);
  transition: color var(--t);
}
.kt td {
  padding: 7px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--dim) 16%, transparent);
  vertical-align: top;
  color: var(--muted);
  transition: color var(--t);
}
.kt tr:last-child td {
  border-bottom: 0;
}
.kt__k {
  width: 10ch;
  padding-right: 16px !important;
  color: var(--ink) !important;
  white-space: nowrap;
}
.kt__k b {
  font-weight: 600;
}

/* The status legend reuses the table but colors the glyph cell. `.kt td` sets a
   dim color at (0,1,1); a bare `.gr` is (0,1,0) and would lose, so the semantic
   colors are re-stated here at (0,2,1) rather than reached for with !important. */
.kt__g {
  width: 12ch;
  padding-right: 16px !important;
  white-space: nowrap;
  font-weight: 600;
}
.kt td.gr {
  color: var(--c-green);
}
.kt td.yl {
  color: var(--c-yellow);
}
.kt td.cy {
  color: var(--c-cyan);
}
.kt td.mg {
  color: var(--c-magenta);
}
.kt td.og {
  color: var(--c-orange);
}
.kt td.rd {
  color: var(--error);
}
.kt td.d {
  color: var(--muted);
}

/* The ? / , overlay body is centred both ways inside the full-screen pane, the
   way the Go's overlayBox lipgloss.Place's it. The block centres as a unit, so
   the columns inside keep their own alignment. */
.overlay {
  height: 100%;
  display: grid;
  place-content: center;
  justify-items: start;
}

/* the , settings list, two columns — same split as the Go's settingsBody */
.scols {
  display: grid;
  grid-template-columns: auto auto;
  gap: 0 32px;
  align-items: start;
}

/* keybindings reference inside the demo's ? overlay */
.kcols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 24px;
}
/* 10ch, not the Go source's Width(8): "left/right" and "no-remote" are 10 and 9
   cells, and lipgloss's Width hard-wraps rather than overflows, so the real TUI
   breaks those two rows mid-word. This shows the layout as intended. */
.kcol {
  display: inline-block;
  width: 10ch;
}

/* ----------------------------------------------------------------- footer -- */

.foot {
  border-top: 1px solid var(--rule);
  /* longhands only: <footer class="shell foot"> also takes .shell's
     `padding: 0 28px`, and a `padding` shorthand here would wipe that gutter and
     run the footer into the viewport edge below the 1180px --measure. */
  padding-top: 32px;
  padding-bottom: 56px;
  display: flex;
  gap: 18px 28px;
  flex-wrap: wrap;
  align-items: center;
  color: var(--muted);
  font-size: 11.5px;
  transition: color var(--t);
}
.foot__sp {
  margin-left: auto;
}

/* ------------------------------------------------------------ responsive -- */

@media (max-width: 860px) {
  :root {
    --lane: 100%;
    --gap: 10px;
  }
  .hero__grid,
  .sec {
    grid-template-columns: minmax(0, 1fr);
  }
  .lane {
    text-align: left;
    padding-top: 0;
  }
  .hero h1 {
    max-width: 100%;
  }
  .shell {
    padding: 0 18px;
  }
  /* the terminal's height must come off .term — .term__body is `flex: 1` inside
     it, so a height here would be overridden by the flex basis and do nothing */
  .term {
    height: 500px;
  }
}

@media (max-width: 560px) {
  .foot__sp {
    margin-left: 0;
  }
}

/* The [ v1.0.8 ] [ light ] [ github ] run needs 392px at desktop sizing, so it
   clears no phone. Buy the space back off the wordmark rather than dropping a
   chip — the three-chip run is the masthead. */
@media (max-width: 430px) {
  .masthead__in {
    gap: 9px;
  }
  .wordmark {
    gap: 8px;
  }
  .wordmark__txt {
    font-size: 17px;
  }
  .bar {
    width: 20px;
    height: 13px;
  }
}
/* Under ~360px even that isn't enough. The version is the one that can go: it's
   repeated in Install and behind the releases link, whereas the ground toggle and
   the repo link are the only ways to reach those from here. */
@media (max-width: 365px) {
  .chip--ver {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---------------------------------------------------------- mobile gate -- */

/* manygit is a keyboard-driven TUI, and the demo above needs 720px of width and
   a real keyboard to be anything but a screenshot. So on a phone the ENTIRE site
   steps aside for a full-screen interstitial — a joke, then (if you insist) a
   stripped read-only pitch. There is no counterpart in the Go: this is a fact
   about the browser you're holding, not about the tool.

   Shown by CSS alone so the message survives with JS off. The real page stays in
   the DOM behind it (crawlers still read every word); the gate script marks it
   `inert` so it also leaves the a11y tree and the tab order. Only tokens already
   proven AA on both grounds are used here — --ink, --muted, --accent — so all
   twelve palettes clear contrast with no new measurements. */

#mgate {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: none; /* the media query below is the only thing that shows it */
  overflow-y: auto;
  background: var(--bg);
  color: var(--ink);
  padding: clamp(28px, 8vh, 56px) 22px;
  font-family: var(--mono);
  line-height: 1.55;
}

@media (max-width: 720px), (hover: none) and (max-width: 900px) {
  html,
  body {
    overflow: hidden; /* the overlay owns the viewport; nothing scrolls behind */
  }
  #mgate {
    display: flex;
    align-items: center;
    justify-content: center;
  }
}

.mg-card {
  width: 100%;
  max-width: 31rem;
  margin: auto; /* scroll-safe centring when a step is taller than the viewport */
}

/* The masthead's light/dark toggle is hidden with the rest of the site on a
   phone, so the gate carries its own in the corner — same [ chip ] look, wired
   by the same controller (demo.js wireMode) off the shared data-mode. Fixed, so
   it stays put while a long step scrolls; a --bg backing keeps text from tangling
   under it. Bigger tap target than the desktop chip. */
.mg-mode {
  position: fixed;
  top: max(12px, env(safe-area-inset-top));
  right: 12px;
  z-index: 2;
  padding: 11px 12px;
  border-radius: 6px;
  background: var(--bg);
  font-size: 12.5px;
  letter-spacing: 0.08em;
}

.mg-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: clamp(28px, 6vh, 44px);
}
.mg-brand .wordmark__txt {
  font-family: var(--display);
  font-size: 21px;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
}

/* one screen at a time, keyed off #mgate[data-step] */
.mg-screen {
  display: none;
}
#mgate[data-step="wall"] .mg-screen[data-when="wall"],
#mgate[data-step="sure"] .mg-screen[data-when="sure"],
#mgate[data-step="in"] .mg-screen[data-when="in"] {
  display: block;
}

.mg-term {
  font-size: 13px;
  color: var(--muted);
  margin: 0 0 4px;
  word-break: break-word;
}
.mg-sigil {
  color: var(--accent);
}
.mg-cur {
  display: inline-block;
  width: 0.55em;
  height: 1.05em;
  margin-left: 2px;
  vertical-align: text-bottom;
  background: var(--accent);
  animation: mg-blink 1.15s steps(1) infinite; /* reduced-motion rule stills it */
}
@keyframes mg-blink {
  50% {
    opacity: 0;
  }
}
.mg-out {
  font-size: 13px;
  color: var(--muted);
  margin: 0 0 22px;
}

.mg-h {
  font-size: clamp(23px, 6.5vw, 29px);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0 0 14px;
}
.mg-h:focus {
  outline: none; /* focused only to reposition the screen reader after a tap */
}

.mg-p {
  font-size: 15px;
  color: var(--muted);
  margin: 0 0 16px;
  max-width: 34ch;
}
.mg-p em {
  color: var(--ink);
  font-style: normal; /* emphasis by colour, not italics, in a mono face */
}
.mg-p--dim {
  font-size: 13.5px;
}
.mg-sign {
  font-size: 13.5px;
  color: var(--muted);
  margin: 26px 0 0;
}

.mg-actions {
  margin-top: 26px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 12px;
}
.mg-btn {
  font-family: var(--mono);
  font-size: 15px;
  font-weight: 600;
  color: var(--bg); /* symmetric with --accent-on-bg, so this clears AA too */
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 8px;
  padding: 13px 18px;
  cursor: pointer;
  text-align: left;
  transition: filter var(--t);
}
.mg-btn:hover {
  filter: brightness(1.07);
}
.mg-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.mg-btn--ghost {
  color: var(--muted);
  background: transparent;
  border-color: transparent;
  font-weight: 500;
  padding: 8px 2px;
  text-align: left;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.mg-btn--ghost:hover {
  filter: none;
  color: var(--ink);
}
