/* Jacquard user guide
 *
 * The page is the app's own screen turned into a document: the same palette, the app's
 * own face on everything that is looked at rather than read, and the same ground the
 * score is read against. What is different is
 * what is in front of it. The app puts tiles on that ground, which are marks the eye
 * picks out; a manual puts paragraphs on it, and a paragraph read over a lattice is a
 * paragraph nobody finishes. So the ground is left as the app draws it and everything
 * that carries words is given a ground of its own to sit on. */

/* The palette
 *
 * One ramp of greys, no gradients, nothing coloured to carry meaning — the app's
 * standing decision, and the values are Style.cs's own. What a thing is saying is said
 * by where it sits on the ramp and by how much air is around it. */

:root {
  color-scheme: dark;

  --background: #161616;      /* Style.Background */
  --panel: #1e1e1e;           /* Style.Panel */
  --panel-line: #3a3a3a;      /* Style.PanelLine */
  --control: #343434;         /* Style.ControlBackground */
  --control-hover: #444444;   /* Style.ControlHover */
  --dot: #4e4e4e;             /* Style.Dot, the lattice */
  --link: #868686;            /* Style.Link */
  --label: #9a9a9a;           /* Style.Label */
  --note-line: #e8e8e8;       /* Style.NoteLine */
  --ink: #f2f2f2;             /* Style.NoteText */

  --radius: 5px;              /* Style.Radius */
  --line: 1px solid var(--panel-line);

  /* The interface's face, and one for the prose. Both from Google Fonts. Jura is the
   * app's own and carries every heading, label and link here — the things that are
   * looked at. Running text is Space Grotesk, which is the one thing on the page that is
   * read rather than looked at: the same flat, drawn geometry as Jura, and unlike Jura
   * cut for paragraphs. */
  --face-ui: "Jura", system-ui, sans-serif;
  --face-text: "Space Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI",
               "Helvetica Neue", Arial, sans-serif;
}

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

html { scroll-behavior: smooth; scroll-padding-top: 1.5rem; }

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

body {
  margin: 0;
  background: var(--background);
  color: var(--ink);
  font-family: var(--face-text);
  font-size: 16px;
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
}

/* Selected text is the pale end of the ramp, which is what engaged means here. */
::selection { background: var(--ink); color: var(--background); }

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

/* The backdrop
 *
 * The plane's lattice, and nothing else: the dot at the centre of every empty cell, at
 * the app's own 30x32 cell with its 4px gutter, so the pitch is the pitch the score is
 * drawn on. It is fixed rather than scrolled, so it stays the ground the document is
 * laid on rather than becoming a pattern that travels with the text. */

.backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;

  background-image: radial-gradient(circle at 1px 1px,
                                    rgba(78, 78, 78, 0.62) 1px, transparent 0);
  background-size: 34px 36px;
  background-position: 15px 16px;
}

/* The rail
 *
 * Where the guide's own links live, now that there is no row across the top and no
 * block along the bottom. It is the app's arrangement rather than a document's: the
 * score runs down the left and the panel of things one reaches for stands at the right
 * of it, staying where it is while the score moves under the hand.
 *
 * It sticks rather than scrolls away, because a link out of a page this long is worth
 * no less at the end of it than at the top. */

.rail {
  position: sticky;
  top: clamp(1.5rem, 4vw, 3rem);
  align-self: start;
  width: 15rem;
}

/* The panel holds the contents as well now, so it is the one thing on the page that can
 * be taller than the window it is pinned in. It is given the window's height less the
 * air above and below it, and scrolls inside itself when the list runs past that —
 * a stuck panel whose foot is off the bottom of the screen is a panel with entries
 * nobody can reach. */
.rail-panel {
  background: rgba(30, 30, 30, 0.88);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: var(--line);
  border-radius: var(--radius);
  padding: 1.1rem 1.2rem;
  max-height: calc(100vh - 2 * clamp(1.5rem, 4vw, 3rem));
  overflow-y: auto;
  overscroll-behavior: contain;
}

.rail .label {
  font-family: var(--face-ui);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--label);
  margin: 0 0 0.5rem;
}

.rail .label + a { margin-top: 0; }
.rail .group + .group { margin-top: 1.25rem; padding-top: 1.25rem; border-top: var(--line); }

/* Every link here is the app's button: a ground on the ramp, the interface's face, and
 * a hand on it moves the ground up a step. */
.rail a {
  display: block;
  font-family: var(--face-ui);
  font-size: 0.9rem;
  letter-spacing: 0.02em;
  color: var(--ink);
  text-decoration: none;
  padding: 0.35rem 0.6rem;
  margin: 0 -0.6rem;
  border-radius: var(--radius);
  transition: background-color 0.12s ease;
}

.rail a:hover { background: var(--control); }

/* The lit state is the pale end of the ramp, which is what engaged means everywhere in
 * this palette. A pale ground does not take the same weight of type as a dark one — dark
 * type on a bright ground is eaten at its edges — so this one keeps the heavier cut that
 * the headings have given up. It is the app's own rule, and it is four words long. */
.rail a[aria-current="page"] {
  background: var(--ink);
  color: var(--background);
  font-weight: 600;
}

.rail a[aria-current="page"]:hover { background: #d2d2d2; }

/* A link that leaves the guide says so, quietly. */
.rail a .out { color: var(--label); float: right; }
.rail a:hover .out { color: var(--ink); }

/* The contents
 *
 * The list of sections stands in the rail with the rest of the guide's own navigation,
 * because it is the same kind of thing as the links beside it: something reached for
 * while reading, not something read. Each entry is a rail link like any other and takes
 * the same ground under the hand.
 *
 * The number and the name are two columns rather than a number with a space after it,
 * so every name begins at one edge whatever its number is, and a name too long for the
 * rail wraps under itself instead of back under the number. The column is fixed at the
 * width of the widest number the list can reach, which is what makes the edge hold. */

.rail .contents ol {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: section;
}

.rail .contents li { counter-increment: section; }

.rail .contents a {
  display: grid;
  grid-template-columns: 1.9em 1fr;
  align-items: baseline;
  font-size: 0.85rem;
  padding: 0.25rem 0.6rem;
  line-height: 1.5;
}

.rail .contents a::before {
  content: counter(section, decimal-leading-zero);
  color: var(--label);
  font-variant-numeric: tabular-nums;
}

.rail .contents a:hover::before { color: var(--ink); }

/* The document */

.page {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  padding: clamp(1.5rem, 4vw, 3rem) clamp(1rem, 4vw, 2.5rem) 5rem;
}

/* Wider than it was, and held to the left rather than centred in the window: the rail
 * is what the right of the screen is for. */
main {
  width: 100%;
  max-width: 52rem;
}

/* Everything on the page is set from the left, the way the panels in the app are: a
 * column of things that all begin at the same edge, so the eye returns to one place. */
.hero { margin-bottom: 3rem; }

/* The page says what it is and gets on with it — at the size a section heading is set
 * at, and no larger. The face is drawn for interface type and does not hold together
 * blown up any more than it does set bold; what makes this the title is that it stands
 * outside the panels, not that it shouts. */
h1 {
  font-family: var(--face-ui);
  font-size: 1.35rem;
  letter-spacing: 0.05em;
  line-height: 1.3;
  margin: 0 0 1.5rem;
}

/* The screenshot runs the width of the column, like everything else. */
.shot {
  margin: 0;
}

.shot img {
  width: 100%;
  height: auto;
  display: block;
  border: var(--line);
  border-radius: var(--radius);
}

/* The panels
 *
 * Everything with words in it sits on one of these, and that is the whole answer to
 * reading a document over a background: the ground under the text is nearly opaque and
 * the blur takes the lattice out from under the line of type, while the air between the
 * panels leaves the backdrop somewhere to be seen. */

.panel {
  background: rgba(30, 30, 30, 0.88);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: var(--line);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 4vw, 2.5rem);
  margin-bottom: 1.5rem;
}

/* A section heading is the app's panel header: a label at the top of a box, and a rule
 * under it that is the only line in the panel.
 *
 * Nothing here is set bold. The face is monoline and light by design, and its heavy cut
 * shuts the counters at the sizes headings are set at — so what says this is a heading
 * is its size, the space it is given and the rule under it, not its weight. */
.panel > h2 {
  font-family: var(--face-ui);
  font-size: 1.35rem;
  letter-spacing: 0.05em;
  line-height: 1.3;
  margin: 0 0 1rem;
  padding-bottom: 0.6rem;
  border-bottom: var(--line);
  scroll-margin-top: 1.5rem;
}

.panel h3 {
  font-family: var(--face-ui);
  font-size: 1.1rem;
  letter-spacing: 0.05em;
  color: var(--label);
  text-transform: uppercase;
  margin: 2.5rem 0 0.75rem;
}

.panel p { margin: 0 0 1.1rem; }
.panel p:last-child { margin-bottom: 0; }

.panel strong { font-weight: 600; color: var(--ink); }

a { color: var(--ink); text-decoration-color: var(--link); text-underline-offset: 3px; }
a:hover { text-decoration-color: var(--ink); }

/* The figures
 *
 * Each one is a picture of a score cut to its own bounds, taken at twice the size the
 * interface is laid out at — so it is shown at half its pixel width and stays sharp on
 * a display with the pixels for it. It carries the app's own background, which is this
 * page's background too, so it is given a line around it to say where the picture ends. */

figure {
  margin: 1.75rem 0;
}

figure img {
  max-width: 100%;
  height: auto;
  border: var(--line);
  border-radius: var(--radius);
  background: var(--background);
}

figcaption {
  font-family: var(--face-ui);
  font-size: 0.8rem;
  color: var(--label);
  margin-top: 0.6rem;
  line-height: 1.5;
}

/* An aside: something true of the thing just described that is not part of describing
 * it. Dimmed rather than boxed, the way the app puts back what is on screen but out of
 * reach. */
.note {
  border-left: 2px solid var(--panel-line);
  padding-left: 1rem;
  margin: 1.5rem 0;
  color: var(--label);
  font-size: 0.95rem;
}

.note p { margin: 0; }

/* The web build's address, which is the one link on the page anybody is looking for. */
.address {
  display: block;
  font-family: var(--face-ui);
  font-size: 1.05rem;
  letter-spacing: 0.01em;
  padding: 0.9rem 1.1rem;
  margin: 1.5rem 0;
  background: var(--background);
  border: var(--line);
  border-radius: var(--radius);
  text-decoration: none;
  word-break: break-all;
  transition: background-color 0.12s ease;
}

.address:hover { background: var(--control); }

/* Keys and buttons named in the text, set in the interface's own face so that a control
 * named on this page looks like the control it names. */
.ui {
  font-family: var(--face-ui);
  letter-spacing: 0.02em;
  background: var(--control);
  border-radius: 3px;
  padding: 0.05em 0.4em;
  font-size: 0.92em;
}

/* The tables
 *
 * A control and what it does is two columns and nothing else, and a run of them is a
 * table rather than a run of paragraphs each restating the shape of the last. The app
 * has no table in it to borrow a look from, so the look is the panel's own carried
 * inwards: a rule under the head, a rule between the rows, and no rule anywhere
 * vertical — the gap between the two columns is what says they are two.
 *
 * The name of the thing is set in the interface's face for the same reason .ui is: the
 * left column is almost always a control, and a control named on this page should look
 * like the control it names. */
.panel table {
  width: 100%;
  border-collapse: collapse;
  margin: 1.5rem 0;
  font-size: 0.95rem;
  line-height: 1.6;
  text-align: left;
}

.panel table th {
  font-family: var(--face-ui);
  font-weight: 400;
  font-size: 0.8rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--label);
  padding: 0 1.25rem 0.6rem 0;
  border-bottom: var(--line);
}

.panel table td {
  padding: 0.7rem 1.25rem 0.7rem 0;
  border-bottom: var(--line);
  vertical-align: top;
}

.panel table tr:last-child td { border-bottom: 0; }
.panel table th:last-child, .panel table td:last-child { padding-right: 0; }

/* The first column names the thing the row is about, so it is set the way a thing on
 * screen is set, and it is kept from wrapping where the text beside it has the whole
 * rest of the width to wrap in. */
.panel table td:first-child {
  font-family: var(--face-ui);
  letter-spacing: 0.02em;
  color: var(--ink);
  white-space: nowrap;
}

/* Narrow enough that a column beside the text is a column of nothing: the rail goes
 * back to being a row above it, which is where it came from. */
@media (max-width: 820px) {
  .page { grid-template-columns: minmax(0, 1fr); }

  .rail {
    position: static;
    width: auto;
    order: -1;
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
  }

  .rail-panel {
    max-height: none;
    overflow: visible;
    flex: 1;
    display: flex;
    align-items: center;
    gap: 0.3rem;
    flex-wrap: wrap;
    padding: 0.5rem 0.6rem;
  }

  .rail .label { display: none; }
  .rail .group { display: contents; }
  .rail .group + .group { margin: 0; padding: 0; border: 0; }
  .rail a { margin: 0; }
  .rail a .out { display: none; }

  /* Twelve sections do not go in a row of links, so the contents drops out of the row
   * and takes the whole width under it, in as many columns as the width will hold. Its
   * label comes back, since down here it is the only thing saying what the list is. */
  .rail .group.contents {
    display: block;
    width: 100%;
    margin: 0.5rem 0;
    padding: 0.5rem 0;
    border-top: var(--line);
    border-bottom: var(--line);
  }

  .rail .group.contents .label { display: block; margin-bottom: 0.25rem; }

  .rail .contents ol {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
    column-gap: 0.5rem;
  }
}

@media (max-width: 480px) {
  body { font-size: 15px; }
  .rail a { font-size: 0.85rem; padding: 0.3rem 0.5rem; }
}

/* Two columns need two columns' worth of width. Below that the row stacks: the name
 * over what it does, which is the same reading in one column instead of two. The head
 * goes, since with the columns gone there is nothing left for it to be the head of —
 * and every table here names its rows in the first cell anyway. */
@media (max-width: 560px) {
  .panel table, .panel table tbody, .panel table tr, .panel table td { display: block; }
  .panel table thead { display: none; }

  .panel table tr { border-bottom: var(--line); padding: 0.7rem 0; }
  .panel table tr:last-child { border-bottom: 0; padding-bottom: 0; }

  .panel table td { padding: 0; border: 0; white-space: normal; }
  .panel table td:first-child { color: var(--label); }
}
