/*
 * Copyright (C) 2016-2026 Kean Johnston.
 * Please see the file licenses/License-NostalgiaCommander.txt for licensing details.
 */

:root {
  /*
   * Charcoal, not black: #1E1E1E is what macOS hands the app as its dark window
   * background, so the site and the program's dark mode are the same shade.
   */
  --page: #1e1e1e;
  --edge: #141414;
  --text: #ffffff;

  /* The accent from Help ▸ About — nc::appAccentColour(). */
  --link: #3ca6c4;

  /* Measured off the background of art/FriendlyGreeting.png; make-images.py agrees. */
  --mustard: #f9b502;

  /*
   * Taken from the logo's own outline. White on the mustard is around 2:1 and
   * unreadable; this is 7:1 and already part of the artwork.
   */
  --masthead-ink: #003177;

  /* A card sits just off the page so its edge reads without a hard border. */
  --surface: #262626;
  --rule: #333333;
  --muted: #bbbbbb;

  --page-max: 1800px;
  --content-pad: 72px;
  --icon-size: 280px;
  /* Half the master's 1947px, so a 2x display lands one device pixel per captured pixel. */
  --shot-max: 974px;

  /* Four windows at once has nothing readable in it anyway, so it yields width to the prose. */
  --layouts-max: 860px;

  --row-gap: 112px;
  --band-gap: 100px;
  --closing-measure: 1120px;

  /* The help page is mostly tables, so it takes more width than the 80ch of the other documents. */
  --help-measure: 1000px;

  /*
   * The download boxes. Each carries one accent, used for its border, its bullets and its
   * button, so a platform is recognisable before you have read a word of it.
   */
  --windows: #00a4ef;
  --macos: #c6ccd2;
  --linux: #ffcc00;
  --platform-logo: 92px;
  --platform-border: 4px;
  /*
   * The visible size of the star, not the font size that draws it — an asterisk's ink fills
   * only about a third of its em box, so the rule below scales up from this to get here.
   */
  --bullet-size: 38px; /* about 1cm */

  /* Header dimensions, kept here because this is what we are still tuning. */
  --strip-pad-top: 14px;
  --strip-pad-bottom: 15px;
  --strip-pad-side: 28px;
  --greeting-height: 260px;
  --title-height: 150px;
  --header-gap: 80px;
  --sticker-size: 210px;
  --sticker-right: 36px; /* inside the strip's side padding, so 64px from its edge */
  --sticker-tilt: 20deg;
}

* {
  box-sizing: border-box;
}

html {
  background: var(--edge);
}

body {
  margin: 0 auto;
  max-width: var(--page-max);
  min-height: 100vh; /* short pages still show the column against the edge bars */
  background: var(--page);
  color: var(--text);

  /*
   * microsoft.com's stack. Segoe UI is Microsoft's own and cannot be served from
   * our domain, so it is named rather than shipped: Windows visitors get it from
   * the OS and everyone else falls through.
   */
  font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 15px;
  line-height: 1.5;
}

a {
  color: var(--link);
}

/*
 * The masthead. The officer is a cutout, so the strip's mustard is the backdrop
 * he was painted against and there is no seam where the image ends.
 */
.masthead {
  /*
   * Three columns with matching outer thirds: the officer and wordmark sit in the
   * middle one and so are centred on the strip itself, not on whatever the sticker
   * leaves over. The sticker lives in the third column and pushes to its end.
   */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: var(--strip-pad-top) var(--strip-pad-side) var(--strip-pad-bottom);
  background: var(--mustard);
}

.brand {
  grid-column: 2;
  display: flex;
  align-items: center;
  gap: var(--header-gap);
}

/* On an inner page the brand is the way home, and the tagline must not pick up a link's underline. */
a.brand {
  text-decoration: none;
}

.masthead .greeting {
  height: var(--greeting-height);
  width: auto;
}

.masthead .title {
  height: var(--title-height);
  width: auto;
}

.wordmark {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.wordmark p {
  margin: 0;
}

.wordmark .tagline {
  margin-top: 14px;
  text-align: center;
  color: var(--masthead-ink);
  font-size: 24px;
  font-weight: 600;
}

/*
 * drop-shadow rather than box-shadow because the badge is a starburst — a box
 * shadow would trace a square nothing in the artwork has.
 */
.sticker {
  grid-column: 3;
  justify-self: end;
  margin-right: var(--sticker-right);
  height: var(--sticker-size);
  width: auto;
  transform: rotate(var(--sticker-tilt));
  filter: drop-shadow(3px 5px 5px rgb(0 0 0 / 0.35));
}

main {
  padding: 76px var(--content-pad) 104px;
}

/*
 * The page below the banner is a stack of bands, and a band is one subject: a block of
 * prose beside a picture, then the boxes that qualify it. The picture changes sides from
 * band to band, but the copy stays first in the source either way and the side is chosen
 * with order — so the reading order is the same on both kinds and a narrow screen stacks
 * them identically.
 */
.band + .band {
  margin-top: var(--band-gap);
}

.row {
  display: flex;
  align-items: center;
  gap: 72px;
}

.row.art-left .row-art {
  order: -1;
}

/*
 * Broad, but not the full 1800px: past about eighty characters the eye loses the start
 * of the next line, and the page is wide enough to hit that easily. In most rows the
 * picture beside it is the tighter limit and this cap never comes into play; it is what
 * stops a row whose picture is small from running the prose the width of the page.
 */
.row-copy {
  flex: 1 1 auto;
  max-width: 80ch;
}

.app-icon {
  flex: none; /* the icon keeps its size and the prose takes the slack */
  width: var(--icon-size);
  height: auto;
}

.shot {
  flex: 1 1 auto;
  min-width: 0;
  max-width: var(--shot-max);
  height: auto;
}

.shot-layouts {
  max-width: var(--layouts-max);
}

.row-copy h1,
.row-copy h2,
.closing h2,
.document h1,
.document h2 {
  margin: 0 0 26px;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.015em;
}

.row-copy h1,
.document h1 {
  font-size: 46px;
}

.row-copy h2,
.closing h2 {
  font-size: 38px;
}

.row-copy p {
  margin: 0 0 22px;
  font-size: 17px;
  line-height: 1.65;
  color: var(--muted);
}

.row-copy .lede {
  font-size: 22px;
  line-height: 1.45;
  color: var(--text);
}

.button {
  display: inline-block;
  margin-top: 14px;
  padding: 15px 38px;
  border-radius: 4px;
  background: var(--mustard);
  color: var(--masthead-ink);
  font-size: 17px;
  font-weight: 700;
  text-decoration: none;
}

.button:hover {
  background: #ffc61a;
}

/*
 * The sign-off, centred rather than in a row because there is no picture to sit beside.
 * A wide measure on purpose: it is the one block on the page with nothing next to it, and
 * a narrow column here left a tall stack of short centred lines down the middle of an
 * otherwise empty page. Set so the note lands in four lines.
 */
.closing {
  margin-top: var(--band-gap);
  text-align: center;
}

.closing p {
  margin: 0 auto;
  max-width: var(--closing-measure);
  font-size: 17px;
  line-height: 1.65;
  color: var(--muted);
}

/*
 * An inner page that is one document rather than a stack of bands, such as the license. A
 * single column at the same eighty-character measure the rows use, centred because there is
 * no picture to share the width with.
 */
.document {
  margin: 0 auto;
  max-width: 80ch;
  font-size: 17px;
}

.document h2 {
  font-size: 30px;
}

.document section + section {
  margin-top: 64px;
}

.document p {
  margin: 0 0 22px;
  line-height: 1.65;
  color: var(--muted);
}

/* The terms themselves sit in a card, so they read as the text of the license and not as copy about it. */
.terms {
  padding: 34px 36px 16px; /* the last paragraph's own margin makes up the bottom */
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--surface);
}

.terms p {
  color: var(--text);
}

.terms .terms-head {
  font-weight: 700;
}

.donate-links {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

/*
 * The third-party list: one section per component, its license texts folded away until opened.
 * Nearly thirty of them at the document's own heading size and spacing read as a wall of
 * headings, so both step down here.
 */
.document .component {
  margin-top: 40px;
}

.component h2 {
  margin-bottom: 10px;
  font-size: 24px;
}

.component .copyright {
  margin-bottom: 12px;
}

.document code,
.license-text summary {
  font-family: ui-monospace, "Cascadia Mono", Consolas, Menlo, "DejaVu Sans Mono", monospace;
}

.license-text summary {
  padding: 3px 0;
  color: var(--link);
  font-size: 15px;
  cursor: pointer;
}

/*
 * The help page: short prose and tables of keys. A key is drawn as a keycap so a chord reads at a
 * glance, and a keycap never breaks across a line, so a long chord moves down whole.
 */
.document.help,
.document.download {
  max-width: var(--help-measure);
}

.document h3 {
  margin: 40px 0 12px;
  font-size: 21px;
  font-weight: 700;
  line-height: 1.25;
}

.document h3 .aside {
  color: var(--muted);
  font-size: 16px;
  font-weight: 400;
}

.keys {
  width: 100%;
  margin: 0 0 22px;
  border-collapse: collapse;
  font-size: 16px;
  line-height: 1.5;
}

.keys th,
.keys td {
  padding: 8px 14px 8px 0;
  border-bottom: 1px solid var(--rule);
  text-align: left;
  vertical-align: top;
}

.keys th {
  color: var(--text);
  font-weight: 700;
}

.keys td {
  color: var(--muted);
}

/*
 * One split for every table of operations, so the keys line up in a single column down the whole
 * page instead of each table placing them by its own longest description. The reference tables
 * at the top (platforms, colours, targeting) are not lists of keys and size to their content.
 */
.keys:not(.legend) td:first-child {
  width: 58%;
}

kbd {
  display: inline-block;
  padding: 0 7px;
  border: 1px solid #4a4a4a;
  border-bottom-width: 2px;
  border-radius: 4px;
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: 14px;
  line-height: 1.6;
  white-space: nowrap;
}

.document .lede {
  font-size: 20px;
  line-height: 1.5;
  color: var(--text);
}

.document .back {
  margin: 0 0 36px;
}

.document .back:last-child {
  margin: 72px 0 0;
}

.document ul.plain {
  margin: 0 0 22px;
  padding-left: 22px;
  color: var(--muted);
  line-height: 1.65;
}

.document ul.plain li + li {
  margin-top: 8px;
}

/*
 * A screenshot, mounted so it reads as a picture of the program rather than part of the page: a
 * raised mat, the capture inside it on a dark edge of its own, and a caption led by a tag that
 * says what it is. A shot is as wide as its picture, centred in the column; a wide one breaks out
 * of the column to the width of the window it shows.
 */
.shot {
  width: fit-content;
  max-width: 100%;
  margin: 30px auto 38px;
  padding: 14px 14px 12px;
  border: 1px solid #3a3a3a;
  border-radius: 14px;
  background: linear-gradient(#2b2b2b, #222222);
  box-shadow: 0 22px 48px rgb(0 0 0 / 0.55), inset 0 1px 0 rgb(255 255 255 / 0.05);
}

.shot.wide {
  width: min(1198px, calc(100vw - 32px));
  max-width: none;
  margin-left: 50%;
  transform: translateX(-50%);
}

.shot-frame {
  position: relative;
  line-height: 0;
}

.shot img {
  display: block;
  max-width: 100%;
  height: auto;
  border: 1px solid #000;
  border-radius: 8px;
  box-shadow: 0 0 0 1px rgb(255 255 255 / 0.06);
}

/* A macOS window capture brings its own edge and rounded, transparent corners; a frame would square them off. */
.shot.mac img {
  border: none;
  border-radius: 0;
  box-shadow: none;
}

.shot.wide img {
  width: 100%;
}

.shot-stack {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/*
 * Zero width, then stretched to the full width: the caption adds nothing to the size the mat takes
 * from its picture, so a long caption wraps under the shot instead of widening it.
 */
.shot figcaption {
  width: 0;
  min-width: 100%;
  margin-top: 12px;
  color: var(--muted);
  font-size: 15px;
  line-height: 1.5;
}

.shot figcaption::before {
  content: "Screenshot";
  display: inline-block;
  margin-right: 10px;
  padding: 0 9px;
  border-radius: 999px;
  background: var(--mustard);
  color: var(--masthead-ink);
  font-size: 12px;
  font-weight: 700;
  line-height: 20px;
}

/*
 * Numbered markers laid over a screenshot, placed in percentages of the picture so they stay on
 * their target at any width, and keyed to a numbered list in the caption drawn the same way.
 */
.callout,
.callouts li::before,
.step,
.steps > li::before {
  display: inline-block;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--mustard);
  color: var(--masthead-ink);
  font-size: 15px;
  font-weight: 700;
  line-height: 28px;
  text-align: center;
}

.callout {
  position: absolute;
  margin: -14px 0 0 -14px;
  box-shadow: 0 0 0 3px rgb(0 0 0 / 0.6), 0 4px 12px rgb(0 0 0 / 0.5);
}

.callouts {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 28px;
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
  counter-reset: callout;
}

.callouts li {
  display: flex;
  align-items: baseline;
  gap: 10px;
  counter-increment: callout;
}

.callouts li::before {
  content: counter(callout);
  flex: none;
}

/*
 * A download page. The two packages sit side by side as cards in the platform's own accent — the
 * colour its box wears on the home page — each with the file it is, what it weighs, and one large
 * button. The button carries the download icon as well as the word, the way a download mirror's
 * does, so it is found before it is read.
 */
.downloads {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 30px;
  margin: 40px 0 22px;
  --accent: var(--windows);
}

.download-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 40px 34px 34px;
  border: var(--platform-border) solid var(--accent);
  border-radius: 16px;
  background: linear-gradient(#272727, #1f1f1f);
  box-shadow: 0 18px 40px rgb(0 0 0 / 0.45);
  text-align: center;
}

.download-card h2 {
  margin: 18px 0 6px;
  font-size: 28px;
}

.download-card p {
  margin: 0 0 12px;
}

.download-card .file {
  color: var(--text);
  font-family: ui-monospace, "Cascadia Mono", Consolas, Menlo, "DejaVu Sans Mono", monospace;
  font-size: 15px;
}

.download-card .facts {
  color: var(--accent);
  font-size: 14px;
  font-weight: 600;
}

.download-icon {
  display: grid;
  place-items: center;
  width: 84px;
  height: 84px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #4cc4f5, var(--accent) 55%, #006fa3);
  box-shadow: 0 8px 22px rgb(0 164 239 / 0.35), inset 0 2px 0 rgb(255 255 255 / 0.25);
}

.download-icon svg,
.download-button svg {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.download-icon svg {
  width: 46px;
  height: 46px;
  color: #ffffff;
  stroke-width: 4;
}

/* Pinned to the bottom of the card, so the two buttons line up whatever the text above them does. */
.download-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  width: 100%;
  margin-top: auto;
  padding: 16px 24px;
  border-radius: 8px;
  background: var(--accent);
  color: #10151a;
  font-size: 19px;
  font-weight: 700;
  text-decoration: none;
  box-shadow: 0 6px 16px rgb(0 0 0 / 0.35);
  transition: transform 0.12s ease, filter 0.12s ease;
}

.download-button:hover {
  filter: brightness(1.12);
  transform: translateY(-1px);
}

.download-button svg {
  width: 24px;
  height: 24px;
  stroke-width: 2.6;
}

.ribbon {
  position: absolute;
  top: 16px;
  right: 16px;
  padding: 2px 12px;
  border-radius: 999px;
  background: var(--mustard);
  color: var(--masthead-ink);
  font-size: 13px;
  font-weight: 700;
}

/* A platform with one package: the card alone, centred, at the width it has when there are two. */
.downloads.single {
  grid-template-columns: minmax(0, calc(50% - 15px));
  justify-content: center;
}

.downloads.macos {
  --accent: var(--macos);
}

.downloads.macos .download-icon {
  background: radial-gradient(circle at 35% 30%, #f2f4f6, var(--accent) 55%, #7d858d);
  box-shadow: 0 8px 22px rgb(198 204 210 / 0.25), inset 0 2px 0 rgb(255 255 255 / 0.35);
}

.downloads.linux {
  --accent: var(--linux);
}

.downloads.linux .download-icon {
  background: radial-gradient(circle at 35% 30%, #ffe680, var(--accent) 55%, #b38f00);
  box-shadow: 0 8px 22px rgb(255 204 0 / 0.3), inset 0 2px 0 rgb(255 255 255 / 0.3);
}

/*
 * A command to type, exactly as it is typed: in the terminal's font, one command a line, and a
 * block of its own so it can be selected and copied whole. A long one scrolls inside its box rather
 * than wrapping, since a wrapped command reads as two.
 */
.command {
  margin: 12px 0 22px;
  padding: 16px 22px;
  overflow-x: auto;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--edge);
  color: var(--text);
  font-family: ui-monospace, "Cascadia Mono", Consolas, Menlo, "DejaVu Sans Mono", monospace;
  font-size: 15px;
  line-height: 1.7;
}

.document .signed-note {
  margin-bottom: 56px;
  font-size: 15px;
  text-align: center;
}

/* The setup's pages two to a row, each in the screenshot mat, at the size the dialog is on screen. */
.shot-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 30px;
  margin: 28px 0 34px;
}

.shot-grid .shot {
  width: auto;
  margin: 0;
}

/* An odd one out at the end sits centred under the pair above it, at the same size. */
.shot-grid .shot:last-child:nth-child(odd) {
  grid-column: 1 / -1;
  justify-self: center;
  width: calc(50% - 15px);
}

.step {
  margin-right: 4px;
  vertical-align: 1px;
}

.steps {
  margin: 0 0 28px;
  padding: 0;
  list-style: none;
  counter-reset: step;
}

/* The number hangs in the margin, so the text of a step stays one flowing paragraph. */
.steps > li {
  position: relative;
  margin-bottom: 14px;
  padding-left: 44px;
  color: var(--muted);
  line-height: 1.65;
  counter-increment: step;
}

.steps > li::before {
  content: counter(step);
  position: absolute;
  top: 0;
  left: 0;
}

/* What an archive holds, drawn as the folder it unpacks to. */
.tree {
  margin: 0 0 22px;
  padding: 18px 22px;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--edge);
  font-family: ui-monospace, "Cascadia Mono", Consolas, Menlo, "DejaVu Sans Mono", monospace;
  font-size: 14px;
  line-height: 1.9;
}

/* The indent is inside the name's column, so every note starts at the same place. */
.tree-row {
  display: grid;
  grid-template-columns: 36ch 1fr;
  gap: 18px;
}

.tree-row.depth-1 .tree-name {
  padding-left: 26px;
}

.tree-row.depth-2 .tree-name {
  padding-left: 52px;
}

.tree-name {
  color: var(--text);
}

.tree-name.dir {
  color: var(--mustard);
}

.tree-note {
  color: var(--muted);
  font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.swatch {
  display: inline-block;
  width: 18px;
  height: 18px;
  margin-right: 10px;
  border-radius: 3px;
  vertical-align: -3px;
}

/*
 * Capped at most of a screen and scrolled inside, so opening one of the long texts (the LGPLs run
 * to five hundred lines) does not push every component after it off the page.
 */
.license-text pre {
  margin: 10px 0 14px;
  padding: 20px 24px;
  max-height: 70vh;
  overflow: auto;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--edge);
  color: var(--text);
  font-size: 13px;
  line-height: 1.5;
}

/*
 * One box per platform. The boxes stretch to a common height, so the button is pushed to
 * the bottom by its own auto margin and the three of them line up however unequal the
 * lists above turn out to be.
 */
.platforms {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 30px;
  margin-top: var(--band-gap);
  scroll-margin-top: 40px; /* jumped to from the hero, so it stops short of the very top edge */
}

.platform {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 42px 38px 38px;
  border: var(--platform-border) solid var(--accent);
  border-radius: 16px;
}

.platform.windows {
  --accent: var(--windows);
}

.platform.macos {
  --accent: var(--macos);
}

.platform.linux {
  --accent: var(--linux);
}

/*
 * Sized by height, not width: the three marks are different shapes, and matching their
 * heights is what makes them look like a set. The masters are already cropped to their
 * own ink, so nothing here is aligning invisible padding.
 */
.platform-logo {
  height: var(--platform-logo);
  width: auto;
}

.platform ul {
  width: 100%;
  margin: 34px 0 32px; /* the bottom margin is the least the button may sit from the list */
  padding: 0;
  list-style: none;
}

.platform li {
  position: relative;
  margin-bottom: 18px;
  padding-left: calc(var(--bullet-size) + 16px);
  font-size: 16px;
  line-height: 1.5;
  color: var(--muted);
}

/*
 * The bullet is a glyph rather than a list marker so it can be given a size and a shadow of
 * its own. The star is drawn far larger than it looks, because the ink fills only the upper
 * third of the em box; that same overhang is why it is pulled back up by a share of its own
 * size to sit level with the first line of the item.
 */
.platform li::before {
  content: "*";
  position: absolute;
  top: calc(var(--bullet-size) * -0.42);
  left: 0;
  font-size: calc(var(--bullet-size) * 2.7);
  line-height: 1;
  color: var(--accent);
  text-shadow: 2px 3px 4px rgb(0 0 0 / 0.6);
}

.platform .button {
  margin-top: auto; /* pinned to the bottom of the box, whatever the list did above it */
  padding: 14px 34px;
  background: var(--accent);
  color: #10151a;
}

.platform .button:hover {
  filter: brightness(1.12);
  background: var(--accent);
}

.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 30px;
  margin-top: var(--row-gap);
}

.card {
  padding: 34px 36px 38px;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--surface);
}

.card h2 {
  margin: 0 0 16px;
  font-size: 23px;
  font-weight: 700;
  line-height: 1.25;
}

.card p {
  margin: 0;
  font-size: 16px;
  line-height: 1.65;
  color: var(--muted);
}
