/* tokens.css */
/*
 * Every colour, size and space in one place. The only file allowed to define
 * a custom property, and the only rule in it is :root.
 *
 * Taken from the approved prototype rather than reinvented — these are
 * decisions that were already made and looked at.
 */
:root {
  /* Surfaces, warm to cool */
  --ground:      #fffaf5;
  --surface:     #ffffff;
  --surface-2:   #f7f5f2;
  --sunken:      #f2f1ef;

  --line:        #e5e2de;
  --line-2:      #cdc9c3;

  /* Ink, darkest to faintest */
  --ink:         #011f2e;
  --ink-2:       #01334b;
  --muted:       #5d7079;
  --faint:       #8b979c;

  /* Encode orange, and the two accents that sit beside it */
  --accent:      #ff4d1c;
  --accent-ink:  #c3350e;
  --accent-wash: #ffecda;

  --lime:        #9cff6e;
  --lime-ink:    #356b18;
  --lime-wash:   #effde8;

  --violet:      #dd86ff;
  --violet-ink:  #7a3a96;
  --violet-wash: #f8ecff;

  --dot: rgba(1, 31, 46, .16);

  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* A small radius everywhere. The reference is square-ish on purpose. */
  --r: 3px;

  /* THE SCALE
   *
   * Ten sizes, named for what a thing IS rather than how big it is, so a new
   * component picks a role instead of guessing a number.
   *
   * Derived from the reference by rounding: it uses nineteen sizes in
   * half-pixel steps, hand-tuned per element, and almost nothing here moves
   * more than half a pixel from what it was. That is invisible on screen, and
   * it is the difference between a scale and a pile of magic numbers — which
   * is how a calendar chip ended up set at the body size.
   */
  /* The reading column. 62ch of the prose face came to 625px, and it is worth
     a name because a picture inside an article should be the width of the
     article — not the width of whatever space the shell happens to leave. */
  --measure:      625px;

  --size-micro:    9.5px;   /* day names, month chips, tags */
  --size-label:   10.5px;   /* eyebrows, rail heads, captions */
  --size-small:   11.5px;   /* view pills, locations, blurbs */
  --size-minor:   12.5px;   /* secondary text, metadata */
  --size-compact:   14px;   /* dates, range labels, compact UI */
  --size-body:      15px;   /* body copy, ledes, section headings */
  --size-strong:    16px;   /* card titles, day numbers */
  --size-title:     19px;   /* the wordmark, prose headings */
  --size-figure:    25px;   /* stat numbers */
  --size-display:   28px;   /* page titles */

  /* The small mono label — eyebrows, rail heads, stat captions, tags. Eight
     components were each guessing at it; these are the reference's values.
     .14em at 10.5px is the 1.47px it actually renders. */
  --label-size:   10.5px;
  --label-weight: 500;
  --label-track:  .14em;

  /* Measured off the reference rather than chosen. The two that matter are
     --space-5, the gap between one section and the next, and --space-3, the
     gap between a section's heading and its contents. Everything read loose
     until these came down. */
  --space-1:  6px;
  --space-2: 12px;
  --space-3: 16px;
  --space-4: 22px;
  --space-5: 36px;
}

/* base.css */
/*
 * Element defaults only. Not one class in this file, ever.
 *
 * Anything that needs a class belongs in a component, and a component may
 * only style its own prefix — which is what stops a rule written for one
 * card quietly reshaping every other thing on the page.
 */
*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  /* 1.6, matching the reference. At 15px that is a 24px rhythm, which is
     what every spacing value here is a multiple or half of. */
  font: var(--size-body)/1.6 var(--sans);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -.01em; }
h1 { font-family: var(--mono); font-size: var(--size-display); }
h2 { font-size: var(--size-title); }
h3 { font-size: var(--size-strong); }

p { margin: 0 0 var(--space-2); }
p:last-child { margin-bottom: 0; }

a { color: inherit; text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 2px; }

img, svg { max-width: 100%; display: block; }

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }

ul, ol { margin: 0; padding: 0; list-style: none; }

hr { border: 0; border-top: 1px solid var(--line); margin: var(--space-4) 0; }

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

/* l-grid.css */
/*
 * As many cards per row as will fit at 184px, which at the 786px content
 * column gives four — and reflows to three or two as the window narrows
 * rather than squeezing four into a space that cannot hold them.
 */
.l-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(184px, 1fr));
  gap: 10px;
}

.l-grid__empty {
  grid-column: 1 / -1;
  padding: var(--space-5) 0;
  color: var(--faint);
  text-align: center;
}

/* l-people.css */
/*
 * As many faces per row as will fit, rather than a fixed count — the grid
 * should reflow with the window instead of leaving a gap.
 */
.l-people {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
  gap: var(--space-2);
}

/* l-shell.css */
/*
 * The frame every page sits in: a fixed sidebar, a main column, and an
 * optional rail down the right. Layout only — no colour decisions beyond the
 * two dividing lines, and nothing about the contents of any of it.
 *
 * Every selector begins .l-shell. There is a test.
 */
.l-shell {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  min-height: 100vh;
}

.l-shell__side {
  display: flex;
  flex-direction: column;
  background: var(--surface-2);
  border-right: 1px solid var(--line);
  padding: var(--space-4) 0 var(--space-3);
  position: sticky;
  top: 0;
  height: 100vh;
}

/* Pushes whatever follows it to the bottom of the sidebar. */
.l-shell__side-fill { flex: 1; }

.l-shell__main {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 296px;
  align-items: start;
  gap: 34px;
  padding: 40px var(--space-4) 72px;
  max-width: 1180px;
  width: 100%;
}

/* 26px, which is between --space-4 and --space-5 and is what the reference
   uses. A rail block is further from its neighbour than anything inside it. */
.l-shell__rail { display: grid; gap: 26px; }

/* A page that paints its own surface takes the whole column: no cap, no
   padding, so its background reaches the sidebar and the window edge. The cap
   exists to keep a line of text readable, and a page with no text to keep
   readable should not inherit a stripe of the old background down its side. */
.l-shell__main--bleed { max-width: none; padding: 0; }


/* One column when there is no rail, so a page can opt out by leaving it empty. */
.l-shell__main:not(:has(.l-shell__rail)) { grid-template-columns: minmax(0, 1fr); }

@media (max-width: 980px) {
  .l-shell { grid-template-columns: 1fr; }
  .l-shell__side { position: static; height: auto; }
  .l-shell__main { grid-template-columns: minmax(0, 1fr); padding: var(--space-4) var(--space-3) var(--space-5); }
}

/* l-signin.css */
/*
 * The sign-in page — the one screen with no shell around it.
 *
 * Structure from docs/prototype/encode-portal.html: a centred card, mono
 * field labels, and the sentence an alum arrives wanting to know.
 *
 * The character comes from encode.pillar.vc, whose hero is a huge halftone
 * circle — a photograph dissolved into dots. Here it is the same treatment
 * used as ground rather than illustration: one large disc bleeding off the
 * left, the card sitting over its edge. Texture, not decoration, and nothing
 * on the page moves.
 */
.l-signin {
  position: relative;
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--space-5) var(--space-3);
  background: var(--ground);
  overflow: hidden;
}

/*
 * The disc. Large enough to read as a field rather than a graphic, anchored
 * off the left edge so it is cropped — which is what stops it looking like a
 * logo somebody centred.
 */
.l-signin::before {
  content: "";
  position: absolute;
  left: -180px;
  top: 50%;
  width: 760px;
  height: 760px;
  transform: translateY(-50%);
  background-image: radial-gradient(var(--accent) 2px, transparent 2.1px);
  background-size: 16px 16px;
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 38%, transparent 70%);
  mask-image: radial-gradient(circle at 50% 50%, #000 38%, transparent 70%);
  opacity: .5;
  pointer-events: none;
}

/* A second, cooler disc off the other side, so the page has a diagonal. */
.l-signin::after {
  content: "";
  position: absolute;
  right: -260px;
  bottom: -220px;
  width: 620px;
  height: 620px;
  background-image: radial-gradient(var(--ink) 1.6px, transparent 1.7px);
  background-size: 14px 14px;
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 34%, transparent 68%);
  mask-image: radial-gradient(circle at 50% 50%, #000 34%, transparent 68%);
  opacity: .16;
  pointer-events: none;
}

.l-signin__card {
  position: relative;
  width: 100%;
  max-width: 372px;
  padding: var(--space-5) var(--space-4) var(--space-4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: 0 1px 2px rgba(1, 31, 46, .04), 0 12px 40px rgba(1, 31, 46, .06);
}

.l-signin__mark {
  font-family: var(--mono);
  font-size: var(--size-title);
  font-weight: 700;
  letter-spacing: .06em;
}

.l-signin__kind {
  display: block;
  margin-top: 3px;
  font-family: var(--mono);
  font-size: var(--label-size);
  letter-spacing: var(--label-track);
  text-transform: uppercase;
  color: var(--faint);
}

/*
 * The line off the fellowship's own front page. Left as a statement rather
 * than a headline: it is the reason somebody is here, and a sign-in page is
 * not the place to sell it twice.
 */
.l-signin__promise {
  margin: var(--space-4) 0 var(--space-5);
  padding-left: var(--space-3);
  border-left: 2px solid var(--accent);
  font-family: var(--mono);
  font-size: var(--size-strong);
  line-height: 1.4;
  letter-spacing: -.01em;
  color: var(--ink);
}

.l-signin__title { margin-bottom: var(--space-1); }

.l-signin__sub { color: var(--muted); font-size: var(--size-body); }

.l-signin__form { display: grid; gap: var(--space-3); margin-top: var(--space-4); }

.l-signin__field label {
  display: block;
  font-family: var(--mono);
  font-size: var(--label-size);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: var(--space-1);
}

.l-signin__field input {
  width: 100%;
  padding: 10px var(--space-2);
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  background: var(--ground);
  line-height: 1.2;
}

.l-signin__field input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-wash);
}

.l-signin__field--bad input { border-color: #b3261e; }

.l-signin__hint { margin-top: 5px; font-size: var(--size-small); color: var(--faint); }

.l-signin__err {
  font-family: var(--mono);
  font-size: var(--size-small);
  color: #b3261e;
  margin-top: var(--space-1);
}

.l-signin__go {
  padding: 11px var(--space-3);
  border: 0;
  border-radius: var(--r);
  background: var(--ink);
  color: var(--ground);
  font-family: var(--mono);
  font-size: var(--size-minor);
  text-align: center;
  transition: background .12s;
}

.l-signin__go:hover { background: var(--accent); }

.l-signin__foot {
  margin-top: var(--space-4);
  padding-top: 18px;
  border-top: 1px solid var(--line);
  font-size: var(--size-minor);
  color: var(--muted);
  line-height: 1.5;
}

@media (max-width: 720px) {
  .l-signin::before { left: -340px; opacity: .3; }
  .l-signin::after { display: none; }
  .l-signin__card { padding: var(--space-4) var(--space-3); }
}

/* c-adm.css */
/*
 * The list of everything in the library.
 *
 * A row per resource rather than a table, because the useful columns are not
 * the same width for every kind and a table would spend its space on the
 * widest one. Drafts are dimmed rather than badged: there is already a word
 * saying "Draft" at the end of the row, and two signals for one fact is one
 * too many.
 */
.c-adm {
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  overflow: hidden;
}

.c-adm__find {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3);
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
}

/* One height for the whole bar.
 *
 * An input, a select, a button and a link do not agree on a box: with the same
 * 8px padding these came out 40, 32, 35 and 33 pixels, because each takes a
 * different line-height and only two of them are the same font size. Stating
 * the height and centring the contents is the only way four different elements
 * sit on one line, and box-sizing is already border-box everywhere. */
.c-adm__q,
.c-adm__kind,
.c-adm__go,
.c-adm__new {
  height: 36px;
  border-radius: var(--r);
}

.c-adm__q {
  flex: 1;
  min-width: 200px;
  padding: 0 12px;
  border: 1px solid var(--line-2);
  background: var(--surface);
  font: inherit;
  font-size: var(--size-compact);
  color: var(--ink);
}

.c-adm__kind {
  padding: 0 10px;
  border: 1px solid var(--line-2);
  background: var(--surface);
  font-family: var(--mono);
  font-size: var(--size-label);
  color: var(--ink);
}

.c-adm__go {
  display: inline-flex;
  align-items: center;
  padding: 0 14px;
  border: 1px solid var(--line-2);
  background: var(--surface);
  font-family: var(--mono);
  font-size: var(--size-label);
  color: var(--ink);
  cursor: pointer;
}

.c-adm__go:hover { border-color: var(--ink); }

.c-adm__clear {
  font-family: var(--mono);
  font-size: var(--size-label);
  color: var(--muted);
}

/* Pushed to the far end: it is the one control here that is not about
   narrowing what you are looking at. */
.c-adm__new {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  padding: 0 14px;
  background: var(--ink);
  font-family: var(--mono);
  font-size: var(--size-label);
  color: var(--ground);
}

.c-adm__new:hover { text-decoration: none; filter: brightness(1.25); }

.c-adm__count {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--line);
  font-family: var(--mono);
  font-size: var(--size-label);
  color: var(--faint);
}

.c-adm__row {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--line);
}

.c-adm__row:last-child { border-bottom: 0; }
.c-adm__row:hover { background: var(--surface-2); }

.c-adm__row--draft { opacity: .58; }

.c-adm__kind-tag {
  flex: none;
  width: 76px;
  font-family: var(--mono);
  font-size: var(--size-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--faint);
}

.c-adm__title {
  flex: 1;
  min-width: 0;
  /* Matched to the author list's name: these are two views of the same
     library and a title should not be smaller in the one you scan. */
  font-size: var(--size-compact);
  color: var(--ink);
}

.c-adm__title:hover { text-decoration: none; color: var(--accent-ink); }

/* Under the title rather than beside it: at this width a second column of
   prose would be four words wide. */
.c-adm__blurb {
  display: block;
  margin-top: 2px;
  overflow: hidden;
  font-size: var(--size-minor);
  color: var(--muted);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.c-adm__tags {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  /* Wide enough that an author chip, two topics and an audience sit on one
     line. At 300px the fourth wrapped and that row alone stood two pixels
     taller, which reads as a wobble down a list of seventy-four. */
  max-width: 390px;
  justify-content: flex-end;
}

.c-adm__topic,
.c-adm__group {
  padding: 2px 7px;
  border-radius: 999px;
  font-family: var(--mono);
  font-size: var(--size-micro);
  white-space: nowrap;
}

.c-adm__topic { background: var(--surface-2); color: var(--muted); }

/* Who can see it is the thing most worth catching by eye on this screen, so
   it is the one tinted thing in the row. */
.c-adm__group { background: var(--violet-wash); color: var(--violet-ink); }
.c-adm__group--all { background: transparent; color: var(--faint); }

.c-adm__toggle { flex: none; }

.c-adm__state {
  width: 58px;
  padding: 3px 0;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  background: var(--surface);
  font-family: var(--mono);
  font-size: var(--size-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--faint);
  cursor: pointer;
}

.c-adm__state--live { border-color: var(--lime-ink); background: var(--lime-wash); color: var(--lime-ink); }

.c-adm__none {
  padding: var(--space-4) var(--space-3);
  font-family: var(--mono);
  font-size: var(--size-compact);
  color: var(--faint);
  text-align: center;
}

@media (max-width: 800px) {
  .c-adm__row { flex-wrap: wrap; }
  .c-adm__tags { max-width: none; justify-content: flex-start; }
  .c-adm__new { margin-left: 0; }
}

/* The byline, on the row. Its own tint because it answers a different question
   from a topic — who, not what. */
.c-adm__who {
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--ground);
  border: 1px solid var(--line);
  font-family: var(--mono);
  font-size: var(--size-micro);
  white-space: nowrap;
  color: var(--muted);
}

/* c-auth.css */
/*
 * The author list.
 *
 * Editable in place rather than through a page per person: there are eight of
 * them and each has two fields, so a list you can correct is fewer clicks than
 * a list that only takes you somewhere else. The credit count is the column
 * that matters — it is what makes "Leonie (4)" beside "Leone Baron (2)" read
 * as a mistake rather than as two people.
 */
.c-auth {
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  overflow: hidden;
}

.c-auth__row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-bottom: 1px solid var(--line);
}

.c-auth__row:last-child { border-bottom: 0; }

/* The way in. Tinted so it reads as an empty row waiting to be filled rather
   than as a person whose details have gone missing. */
.c-auth__row--new { background: var(--surface-2); }
.c-auth__row--new:hover { background: var(--surface-2); }
.c-auth__row:hover { background: var(--surface-2); }

/* The fields and their picture save together, so they are one form. */
.c-auth__edit {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex: 1;
  min-width: 0;
}

.c-auth__face {
  width: 46px;
  height: 46px;
  flex: none;
  border-radius: 50%;
  object-fit: cover;
}

.c-auth__face--none {
  display: grid;
  place-items: center;
  border: 1px dashed var(--line-2);
  background: var(--ground);
  font-family: var(--mono);
  font-size: var(--size-micro);
  color: var(--faint);
}

.c-auth__fields {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}

/* Borderless until touched: eight rows of boxed inputs is a form, and this is
   meant to read as a list that happens to be editable. */
.c-auth__name,
.c-auth__title {
  width: 100%;
  padding: 2px 6px;
  border: 1px solid transparent;
  border-radius: var(--r);
  background: transparent;
  font: inherit;
  /* Stated, because an input left to itself takes a line-height near 1.6 and
     two of them stacked then stand taller than the portrait beside them —
     which is what made the row grow when the type got bigger. */
  line-height: 1.25;
}

/* No colour above: the name reads as the row's title and the role as its
   note, so setting one for both and overriding it twice would leave a line
   that does nothing. */
.c-auth__name { font-size: var(--size-compact); color: var(--ink); }
.c-auth__title { font-size: var(--size-minor); color: var(--muted); }

.c-auth__name:hover,
.c-auth__title:hover { border-color: var(--line); }

.c-auth__name:focus,
.c-auth__title:focus {
  border-color: var(--line-2);
  background: var(--surface);
  outline: 2px solid var(--accent);
  outline-offset: -1px;
}

/* The label IS the button. The real input sits behind it at one pixel rather
   than display:none, so it keeps its place in the tab order and a focus ring
   can be drawn on the label around it. */
.c-auth__pic {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  /* Fixed, because the word inside it changes with the row — "Replace" is
     twelve pixels wider than "Photo", and a button that changes width by its
     label leaves a ragged left edge down a column of otherwise square rows. */
  width: 90px;
  padding: 5px 0;
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  background: var(--surface);
  font-family: var(--mono);
  font-size: var(--size-label);
  color: var(--muted);
  cursor: pointer;
}

.c-auth__pic:hover { border-color: var(--ink); color: var(--ink); }
.c-auth__pic:focus-within { outline: 2px solid var(--accent); outline-offset: -1px; }

.c-auth__pic input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.c-auth__pic svg { width: 14px; height: 14px; }

.c-auth__save {
  flex: none;
  padding: 5px 12px;
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  background: var(--surface);
  font-family: var(--mono);
  font-size: var(--size-label);
  color: var(--ink);
  cursor: pointer;
}

.c-auth__save:hover { border-color: var(--ink); }

.c-auth__count {
  flex: none;
  width: 104px;
  text-align: right;
  font-family: var(--mono);
  font-size: var(--size-micro);
  color: var(--muted);
}

.c-auth__count:hover { color: var(--accent-ink); }

.c-auth__del {
  flex: none;
  padding: 5px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  font-family: var(--mono);
  font-size: var(--size-label);
  color: var(--accent-ink);
  cursor: pointer;
}

.c-auth__del:hover { border-color: var(--accent); }

@media (max-width: 1000px) {
  .c-auth__row { flex-wrap: wrap; }
  .c-auth__edit { flex: 1 1 100%; }
  .c-auth__count { width: auto; text-align: left; }
}

/* c-brand.css */
/*
 * The wordmark at the top of the sidebar.
 */
.c-brand { padding: 0 var(--space-3) var(--space-4); }

.c-brand__mark {
  font-family: var(--mono);
  font-size: var(--size-title);
  font-weight: 700;
  letter-spacing: .06em;
}

.c-brand__sub {
  display: block;
  margin-top: 2px;
  font-family: var(--mono);
  font-size: var(--size-label);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--faint);
}

/* c-brief.css */
/*
 * The briefing you hand to an assistant.
 *
 * A wall of monospace on a page of prose, which is what it is: not something
 * to read here, something to take somewhere else. So it is boxed, scrollable
 * and capped in height — long enough to see what kind of thing it is, short
 * enough that the rest of Settings is still reachable underneath.
 */
.c-brief {
  margin-bottom: var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  overflow: hidden;
}

.c-brief__top {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3);
  border-bottom: 1px solid var(--line);
}

.c-brief__what {
  margin: 0;
  flex: 1;
  font-size: var(--size-compact);
  line-height: 1.45;
  color: var(--muted);
}

.c-brief__copy {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 7px 13px;
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  background: var(--surface);
  color: var(--ink);
  font-family: var(--mono);
  font-size: var(--size-label);
  cursor: pointer;
}

.c-brief__copy:hover { border-color: var(--ink); }

.c-brief__copy svg { width: 15px; height: 15px; }

/* Said rather than shown: the button reports what happened in its own label,
   so there is no toast to place and nothing to dismiss. */
.c-brief__copy[data-said="done"] { border-color: var(--lime-ink); color: var(--lime-ink); }
.c-brief__copy[data-said="failed"] { border-color: var(--accent); color: var(--accent-ink); }

.c-brief__text {
  max-height: 340px;
  overflow: auto;
  margin: 0;
  padding: var(--space-3);
  background: var(--surface-2);
  font-family: var(--mono);
  font-size: var(--size-label);
  line-height: 1.55;
  color: var(--muted);
  white-space: pre-wrap;
  word-break: break-word;
}

@media (max-width: 700px) {
  .c-brief__top { flex-direction: column; align-items: stretch; }
  .c-brief__copy { justify-content: center; }
}

/* c-callout.css */
/*
 * A box that says one thing and offers one way to act on it. The Slack
 * channel, hosting an event, the other office.
 */
.c-callout {
  display: block;
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: var(--space-2);
}

.c-callout--link:hover { border-color: var(--line-2); text-decoration: none; }

/* One that follows a block rather than heading one. */
.c-callout--follows { margin-top: var(--space-4); }

.c-callout__row { display: grid; grid-template-columns: 38px minmax(0, 1fr); gap: var(--space-3); align-items: start; }

.c-callout__badge {
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: var(--r);
  background: var(--lime-wash);
  color: var(--lime-ink);
  font-family: var(--mono);
  font-size: var(--size-body);
}

.c-callout__head { font-family: var(--mono); font-size: var(--size-strong); font-weight: 600; }
.c-callout__body { margin-top: var(--space-1); color: var(--muted); font-size: var(--size-compact); }
.c-callout__arrow { position: absolute; top: var(--space-2); right: var(--space-2); color: var(--faint); font-size: var(--size-small); }

/* The Boston panel, which is a different place and says so. */
.c-callout--warm {
  background: #fff6ef;
  border-color: var(--accent);
}

.c-callout--warm .c-callout__head { color: var(--accent-ink); }

/* The banner. Solid accent across the top with the city knocked out of it —
   the one treatment that survived, after a dozen attempts at a small Boston
   landmark that all turned to mush at 22px. A word does not blur. */
.c-callout--banner { padding-top: 0; overflow: hidden; }

.c-callout__bar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 calc(var(--space-2) * -1) var(--space-2);
  padding: 6px var(--space-2);
  background: var(--accent);
  color: var(--ground);
  font-family: var(--mono);
  font-size: var(--size-micro);
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
}

.c-callout__bar svg { width: 14px; height: 14px; flex: none; fill: var(--ground); }

/* The address, quieter than the city and pushed to the far end. */
.c-callout__at { margin-left: auto; font-weight: 500; letter-spacing: .1em; opacity: .78; }

/* The city itself, above the desks. A room full of chairs could be anywhere. */
.c-callout__band {
  margin-top: var(--space-2);
  aspect-ratio: 16 / 7;
  overflow: hidden;
  border: 1px solid var(--accent);
  border-radius: var(--r);
  background: var(--sunken);
}

.c-callout__band img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Somebody else's photograph, under a licence that asks for this line. */
.c-callout__cred {
  display: block;
  margin-top: var(--space-1);
  font-family: var(--mono);
  font-size: var(--size-micro);
  color: var(--faint);
}

.c-callout__shots { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-1); margin-top: var(--space-2); }

.c-callout__shot {
  position: relative;
  aspect-ratio: 1;
  overflow: hidden;
  border: 1px solid var(--accent);
  border-radius: var(--r);
  background: var(--sunken);
}

.c-callout__shot img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }


/* c-card.css */
/*
 * A resource, as a card. One size, two shapes.
 *
 * Every card is 292px tall. Fixed, not stretched to whatever the tallest
 * thing in the row happens to need — a grid of cards that each grow to fit
 * their own text is a grid of different-sized holes, and the rows get taller
 * every time somebody writes a longer blurb.
 *
 * A guide with a photograph fills the card and lays its title over the
 * bottom. Everything else puts a 112px panel on top and the words beneath.
 * Which shape a card takes comes from resource_kind.treatment, so it is a
 * property of the data rather than a branch somebody has to remember.
 */
.c-card {
  position: relative;
  height: 292px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
}

.c-card:hover { border-color: var(--accent); transform: translateY(-1px); text-decoration: none; }


/* ---- the panel: a photograph, or a field with a mark on it ---- */

.c-card__top {
  position: relative;
  height: 112px;
  flex: none;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
  background: var(--sunken);
}

.c-card__top img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.c-card__field {
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  background-image: radial-gradient(var(--dot) 1px, transparent 1px);
  background-size: 9px 9px;
}

.c-card__field--warm { background-color: #fff6ef; background-image: radial-gradient(rgba(255,77,28,.28) 1px, transparent 1px); }
.c-card__field--cool { background-color: var(--surface-2); }

.c-card__tile {
  min-width: 44px;
  height: 44px;
  padding: 0 10px;
  display: grid;
  place-items: center;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  font-family: var(--mono);
  font-size: var(--size-body);
  font-weight: 600;
  color: var(--ink-2);
}

.c-card__tile--wide { font-size: var(--size-small); letter-spacing: .02em; }

/* The mark inside a tile. Sized here rather than in c-icon, so the same icon
   can be one size on a card and another in the feed. */
.c-card__mark { display: block; width: 20px; height: 20px; }


/* ---- a recording ---- */

.c-card__play { position: absolute; inset: 0; display: grid; place-items: center; }

.c-card__play span {
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(255, 250, 245, .95);
  box-shadow: 0 3px 14px rgba(1, 31, 46, .34);
  color: var(--ink);
  font-size: var(--size-strong);
  padding-left: 3px;
}

.c-card__mins {
  position: absolute;
  right: 8px;
  bottom: 8px;
  padding: 3px 8px;
  border-radius: var(--r);
  background: rgba(1, 31, 46, .9);
  color: var(--ground);
  font-family: var(--mono);
  font-size: var(--size-small);
  font-weight: 600;
  letter-spacing: .02em;
}


/* ---- the words ---- */

.c-card__body {
  padding: 11px var(--space-2) 10px;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

/* Three lines, not two. The column is 184px at its narrowest and a title like
   "How to raise a seed as a science founder" wants the room; the blurb below
   is the thing that can afford to be cut short. */
.c-card__title {
  font-size: var(--size-body);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -.005em;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.c-card__blurb {
  margin-top: 5px;
  font-size: var(--size-small);
  line-height: 1.45;
  color: var(--muted);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}


/* ---- the bottom slot: who to ask, and at most one fact ---- */

/* Stacked rather than side by side: at 184px a name and a fact on one line
   left the name about 20px and clipped every one of them to a letter.
   column-reverse, so the markup reads author-then-fact while the fact renders
   above the byline. */
.c-card__foot {
  margin-top: auto;
  padding-top: 9px;
  display: flex;
  flex-direction: column-reverse;
  align-items: flex-start;
  gap: 5px;
  width: 100%;
  min-width: 0;
}

.c-card__by { display: flex; align-items: center; gap: 8px; max-width: 100%; min-width: 0; }

.c-card__ava {
  width: 23px;
  height: 23px;
  flex: none;
  border-radius: 50%;
  object-fit: cover;
  background: var(--sunken);
}

.c-card__who { min-width: 0; }

.c-card__name {
  display: block;
  font-size: var(--size-small);
  font-weight: 500;
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.c-card__role {
  display: block;
  font-family: var(--mono);
  font-size: var(--size-micro);
  line-height: 1.3;
  color: var(--faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.c-card__fact {
  font-family: var(--mono);
  font-size: var(--size-label);
  color: var(--accent-ink);
  white-space: nowrap;
}

/* What it is about, under who made it — the order the Founder Playlist uses,
   and the right one: the name is the thing you recognise, the topics are the
   thing you navigate by. */
.c-card__topics {
  max-width: 100%;
  font-family: var(--mono);
  font-size: var(--size-micro);
  color: var(--faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.c-card__tag {
  position: absolute;
  top: 7px;
  right: 7px;
  padding: 2px 6px;
  border-radius: var(--r);
  font-family: var(--mono);
  font-size: var(--size-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  background: var(--lime-wash);
  color: var(--lime-ink);
}

.c-card__tag--closed { background: var(--violet-wash); color: var(--violet-ink); }


/* ---- a guide with a photograph: the panel fills, the words sit over it ---- */

.c-card--over .c-card__top { height: 100%; border-bottom: 0; }

/* Two things make the words legible, not one: the photograph is dimmed and a
   scrim sits over the bottom half. The gradient alone left the byline sitting
   on whatever the picture happened to be doing there. */
.c-card--over .c-card__top img { filter: brightness(.58) contrast(.94); }

.c-card--over .c-card__body {
  position: absolute;
  inset: auto 0 0 0;
  flex: none;
  padding: 30px var(--space-2) var(--space-2);
  background: linear-gradient(rgba(1, 31, 46, 0), rgba(1, 31, 46, .72) 30%, rgba(1, 31, 46, .95) 62%);
  color: var(--ground);
}

.c-card--over .c-card__title { font-size: var(--size-strong); }
.c-card--over .c-card__blurb { color: var(--ground); opacity: .82; }
.c-card--over .c-card__foot { padding-top: 8px; }
.c-card--over .c-card__fact { color: var(--lime); }
.c-card--over .c-card__name { color: var(--ground); }
.c-card--over .c-card__role,
.c-card--over .c-card__topics { color: rgba(255, 250, 245, .62); }

/* c-collage.css */
/*
 * One large photograph with two smaller ones stacked beside it.
 */
.c-collage {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  grid-template-rows: repeat(2, minmax(0, 1fr));
  gap: var(--space-2);
  aspect-ratio: 16 / 8;
  margin-bottom: var(--space-4);
}

.c-collage__big { grid-row: span 2; }

.c-collage__cell {
  position: relative;
  overflow: hidden;
  border-radius: var(--r);
  background: var(--sunken);
}

.c-collage__cell img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

@media (max-width: 700px) { .c-collage { grid-template-columns: minmax(0, 1fr); aspect-ratio: 4 / 3; } .c-collage__big { grid-row: auto; } }

/* c-days.css */
/*
 * A bar per day, and the two switches above it.
 *
 * The tallest day is 100% and every other is a share of it, so this reads as
 * shape rather than volume — which is the honest thing to show when three days
 * of traffic is all there is. A y-axis would imply a precision the numbers do
 * not have.
 */
.c-days__switch {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

.c-days__gap { flex: 1; }

.c-days__since {
  margin-left: var(--space-2);
  font-family: var(--mono);
  font-size: var(--size-micro);
  color: var(--faint);
}

.c-days__opt {
  padding: 4px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-family: var(--mono);
  font-size: var(--size-label);
  color: var(--muted);
}

.c-days__opt:hover { text-decoration: none; border-color: var(--ink); color: var(--ink); }

.c-days__opt--on { border-color: var(--ink); background: var(--ink); color: var(--ground); }

.c-days {
  display: flex;
  align-items: flex-end;
  justify-content: flex-start;
  gap: 3px;
  height: 132px;
  padding: var(--space-3) var(--space-3) 0;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
}

/* Capped, so three days of data are three bars and not three slabs. A day is
   a day whether there are three of them or ninety. */
.c-days__one {
  flex: 1;
  min-width: 0;
  max-width: 44px;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  gap: 5px;
}

/* A minimum, so a day with one request is still a mark rather than nothing.
   The difference between "quiet" and "closed" is worth seeing. */
.c-days__bar {
  width: 100%;
  min-height: 2px;
  border-radius: 2px 2px 0 0;
  background: var(--accent);
}

.c-days__one:hover .c-days__bar { background: var(--accent-ink); }

.c-days__tick {
  font-family: var(--mono);
  font-size: var(--size-micro);
  color: var(--faint);
  padding-bottom: var(--space-2);
}

/* c-detail.css */
/*
 * The shape both detail pages share: a way back, an opening, an optional
 * photograph, then the body with its facts beside it.
 */
/* The article, at the width of the article. Everything in it agrees: the back
   link, the title, the picture, the prose and the cards underneath. */
.c-detail__column { max-width: var(--measure); }

.c-detail__back {
  display: inline-block;
  margin-bottom: var(--space-3);
  font-family: var(--mono);
  font-size: var(--size-compact);
  color: var(--muted);
}

.c-detail__back:hover { color: var(--accent-ink); }


/* ---- the opening: kind and access, then the mark beside the title ---- */

.c-detail__line { display: flex; align-items: center; gap: var(--space-2); }

.c-detail__only {
  padding: 2px 7px;
  border-radius: var(--r);
  background: var(--lime-wash);
  color: var(--lime-ink);
  font-family: var(--mono);
  font-size: var(--size-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
}

.c-detail__only--closed { background: var(--violet-wash); color: var(--violet-ink); }

.c-detail__head { display: flex; align-items: center; gap: var(--space-3); }

/* Not links yet — there is nowhere for them to go until the library can be
   filtered by topic. They still earn their place: "Biotech · Legal" is how
   somebody decides in a second whether this is the page they wanted. */
.c-detail__topics { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--space-2); }

.c-detail__topic {
  padding: 3px 9px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  font-family: var(--mono);
  font-size: var(--size-micro);
  color: var(--muted);
}

/* A file gets a mark and a piece of writing does not — the same split the
   cards make, so a template looks like a template on both. */
.c-detail__mark {
  width: 52px;
  height: 52px;
  flex: none;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  color: var(--ink-2);
}

.c-detail__mark svg { width: 26px; height: 26px; }

/* The byline. On a card this is a 23px face in a 184px column; here there is
   room for it to read as an article's author line. */
.c-detail__by {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: var(--space-3);
}

.c-detail__ava {
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: 50%;
  object-fit: cover;
  background: var(--sunken);
}

.c-detail__name { font-size: var(--size-compact); font-weight: 500; line-height: 1.25; }

.c-detail__role {
  font-family: var(--mono);
  font-size: var(--size-label);
  line-height: 1.3;
  color: var(--faint);
}

/* The picture belongs to the article, so it is the width of the article. Given
   the whole column it came out 1136px wide against 625px of text, and read as
   a banner the page had been hung on rather than an illustration of it. */
.c-detail__hero {
  max-width: var(--measure);
  overflow: hidden;
  border-radius: var(--r);
  background: var(--sunken);
  margin: var(--space-4) 0;
}

/* Height from the file's own proportions rather than a ratio chosen here. The
   width and height attributes on the tag give the browser the shape before the
   bytes arrive, so nothing jumps. */
.c-detail__hero img { display: block; width: 100%; height: auto; }

/* A Luma cover is a poster with type on it, and cropping one to a band cut the
   words off. Shown whole and at its own proportions, the way Luma shows it —
   held to 380px so a square does not take the whole page. */
.c-detail__poster {
  max-width: 380px;
  margin: var(--space-4) 0;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--sunken);
}

.c-detail__poster img { display: block; width: 100%; height: auto; }

/* The button and the count, side by side: what to do and how many are already
   doing it. */
.c-detail__row { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }

.c-detail__going { font-size: var(--size-compact); color: var(--muted); }
.c-detail__going strong { font-size: var(--size-strong); font-weight: 600; color: var(--accent-ink); }

.c-detail__go {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
  padding: 10px var(--space-4);
  border-radius: var(--r);
  background: var(--ink);
  color: var(--ground);
  font-family: var(--mono);
  font-size: var(--size-compact);
  font-weight: 600;
}

.c-detail__go:hover { background: var(--accent); text-decoration: none; }

/* Stacked, in one box. As a two-column table with a 120px key column and a
   rule under every row it read as a database dump, and "Allocation" and
   "Eligibility" — the only lines that were about this resource rather than
   about the software — carried no more weight than the rest. */
.c-detail__facts {
  max-width: 420px;
  margin-top: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
}

.c-detail__fact { padding: 10px var(--space-2) 11px; }
.c-detail__fact + .c-detail__fact { border-top: 1px solid var(--line); }

.c-detail__key {
  font-family: var(--mono);
  font-size: var(--size-micro);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--faint);
}

.c-detail__value { margin-top: 3px; font-size: var(--size-compact); line-height: 1.4; }

/* A fact with something in the gutter: a calendar tile or a mark, then the
   words. Only the event rail uses it — a resource's facts are a label over a
   value and want no gutter at all. */
.c-detail__pair { display: flex; align-items: flex-start; gap: 10px; }
.c-detail__pair .c-detail__value { margin-top: 0; }

/* Centred in the same 42px gutter the calendar tile occupies, so the three
   rows share a column instead of the icons hugging the left edge while the
   tile sits beside them. 22px because at 17 they read as specks next to it. */
.c-detail__glyph {
  width: 22px;
  height: 22px;
  flex: none;
  margin: 1px 10px 0;
  color: var(--muted);
}

/* The date, as a date. It is the fact somebody came to the page for, and three
   rows of the same grey label made it just another line. */
.c-detail__cal {
  width: 42px;
  flex: none;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  text-align: center;
  line-height: 1;
}

.c-detail__cal-m {
  display: block;
  padding: 3px 0 2px;
  background: var(--accent);
  color: var(--ground);
  font-family: var(--mono);
  font-size: var(--size-micro);
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.c-detail__cal-d {
  display: block;
  padding: 5px 0 6px;
  font-family: var(--mono);
  font-size: var(--size-title);
  font-weight: 600;
}

.c-detail__sub {
  display: block;
  margin-top: 2px;
  font-family: var(--mono);
  font-size: var(--size-small);
  color: var(--muted);
}

/* Housekeeping at the foot of the page. */
.c-detail__checked {
  margin-top: var(--space-4);
  font-family: var(--mono);
  font-size: var(--size-label);
  color: var(--faint);
}

.c-detail__checked--stale { color: var(--accent-ink); }

.c-detail__when {
  font-family: var(--mono);
  font-size: var(--size-strong);
  font-weight: 600;
  color: var(--accent-ink);
  margin-bottom: var(--space-2);
}

.c-detail__numbers { display: flex; gap: var(--space-5); margin: var(--space-4) 0; }
.c-detail__figure { font-family: var(--mono); font-size: var(--size-display); font-weight: 600; line-height: 1; }
.c-detail__of { font-family: var(--mono); font-size: var(--size-micro); letter-spacing: .12em; text-transform: uppercase; color: var(--faint); margin-top: var(--space-1); }

/* c-doors.css */
/*
 * Who may walk in: fellows on the left, everybody else on the right.
 *
 * Two boxes rather than two tabs. The page is read by people who are already
 * signed in, so the hub knows which answer applies to them — and a control that
 * hides one four-line paragraph behind another was asking them to make a choice
 * they had made by being who they are. It also meant a visitor could not see the
 * rule that applied to them without finding a tab and pressing it.
 *
 * Equal columns, deliberately. Whichever one you are, the other is the one you
 * quote to somebody who asks whether they can come — and neither is the small
 * print of the other.
 */
.c-doors {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(255px, 1fr));
  gap: 10px;
  margin: var(--space-4) 0;
}

.c-doors__one {
  padding: 15px 17px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
}

/* The accent, as on the counts elsewhere: the one word that tells you whether
   the paragraph beneath is addressed to you. */
.c-doors__who {
  margin-bottom: 7px;
  font-family: var(--mono);
  font-size: var(--size-micro);
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--accent);
}

.c-doors__lead {
  margin-bottom: 5px;
  font-size: var(--size-body);
  font-weight: 600;
  color: var(--ink);
}

.c-doors__body {
  margin: 0;
  font-size: var(--size-minor);
  color: var(--muted);
}

/* c-facts.css */
/*
 * The address, how to get in, and when it is open.
 */
/* The map the prototype puts above the address. A picture, not a live tile
   layer — nobody needs to pan around King's Cross to find the door. */
.c-facts__map {
  display: block;
  aspect-ratio: 8 / 5;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface-2);
}

.c-facts__map img { width: 100%; height: 100%; object-fit: cover; }

.c-facts__cred {
  display: block;
  margin: var(--space-1) 0 var(--space-2);
  font-family: var(--mono);
  font-size: var(--size-micro);
  color: var(--faint);
}

.c-facts {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: var(--space-2);
  font-size: var(--size-compact);
}

.c-facts__where { font-weight: 600; line-height: 1.45; }
.c-facts__near { color: var(--muted); }
.c-facts__note { margin-top: var(--space-2); color: var(--muted); line-height: 1.5; }
.c-facts__note strong { color: var(--ink); }

.c-facts__hours { margin-top: var(--space-2); border-top: 1px solid var(--line); padding-top: var(--space-1); }

.c-facts__hour {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  padding: 3px 0;
  font-family: var(--mono);
  font-size: var(--size-small);
}

.c-facts__hour span:last-child { color: var(--muted); }

/* c-feed.css */
/*
 * What has changed lately: a tinted glyph, a title with a badge, a line of
 * explanation, and when.
 */
.c-feed {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
}

.c-feed__row {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) auto;
  gap: var(--space-2);
  align-items: start;
  /* Tighter down the page than across it. The 44px mark sets the row height,
     so vertical padding is the only thing that decides how much of the feed
     is feed; the inset from the card edge is doing a different job. */
  padding: var(--space-2) var(--space-3);
  border-top: 1px solid var(--line);
}

.c-feed__row:first-child { border-top: 0; }
.c-feed__row:hover { background: var(--surface-2); text-decoration: none; }

/* Larger than the reference's 34px, deliberately. A feed of five rows all
   the same weight reads as one texture, and the mark is the only thing that
   tells them apart at a glance. */
.c-feed__glyph {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 5px;
  font-family: var(--mono);
  font-size: var(--size-minor);
  font-weight: 600;
  background: var(--sunken);
  color: var(--muted);
}

.c-feed__glyph--recording { background: var(--violet-wash); color: var(--violet-ink); }
.c-feed__glyph--template  { background: var(--lime-wash);   color: var(--lime-ink); }
.c-feed__glyph--vendor    { background: var(--accent-wash); color: var(--accent-ink); }
.c-feed__glyph--credit    { background: var(--accent-wash); color: var(--accent-ink); }
.c-feed__glyph--guide     { background: var(--sunken);      color: var(--ink-2); }

.c-feed__mark { display: block; width: 23px; height: 23px; }

/* Where a resource has a picture, the picture is the mark. The tinted glyph is
   what a thing looks like when it has none, and it says only what kind it is —
   which the row already says. */
.c-feed__shot {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 5px;
  object-fit: cover;
}

.c-feed__title { display: block; font-weight: 600; font-size: var(--size-compact); }

.c-feed__badge {
  margin-left: var(--space-1);
  padding: 1px 5px;
  border-radius: var(--r);
  font-family: var(--mono);
  font-size: var(--size-micro);
  letter-spacing: .1em;
  vertical-align: 2px;
  background: var(--accent-wash);
  color: var(--accent-ink);
}

.c-feed__badge--updated { background: var(--sunken); color: var(--muted); }

.c-feed__blurb { display: block; margin-top: 2px; font-size: var(--size-minor); color: var(--muted); }

/* Centred, not aligned to the top like its neighbours. The row is start-
   aligned because the title and the blurb read from the top down and the mark
   fills the height exactly — but the date is one line with nothing under it,
   and sitting it at the top left it eleven pixels above everything else. */
.c-feed__when {
  align-self: center;
  font-size: var(--size-compact);
  color: var(--faint);
  white-space: nowrap;
}

.c-feed__empty { padding: var(--space-3); color: var(--faint); font-size: var(--size-compact); }

/* c-filters.css */
/*
 * Search, then a pill per kind with how many there are.
 *
 * Two rows, not one. Search takes the full width on its own line and the
 * pills sit beneath — a narrow search box wedged in beside seven filters
 * wraps at the first awkward width and puts the last two pills on a line by
 * themselves.
 *
 * The pills are small on purpose. They are a way of narrowing a list, not the
 * subject of the page, and at 14px in a 16px pill they were competing with
 * the cards underneath them.
 */
.c-filters {
  display: grid;
  gap: 8px;
  margin-bottom: var(--space-4);
}

/* Square-ish, like every other input. Only the pills are round. */
.c-filters__search {
  width: 100%;
  padding: 8px 11px;
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  background: var(--surface);
  font-size: var(--size-minor);
  /* base.css hands inputs the body's 1.6, which is right for a paragraph and
     makes a single-line field five pixels too tall. */
  line-height: 1.2;
}

.c-filters__search:focus { outline: none; border-color: var(--accent); }

.c-filters__row { display: flex; flex-wrap: wrap; gap: 6px; }

.c-filters__pill {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  padding: 5px 10px;
  border: 1px solid var(--line-2);
  border-radius: 100px;
  font-size: var(--size-small);
  line-height: 1.6;
  color: var(--ink-2);
}

.c-filters__pill:hover { background: var(--surface); text-decoration: none; }

.c-filters__pill[aria-current="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--ground);
}

/*
 * The count in the accent, matching the tabs on Community — it is the one
 * thing in the row worth scanning down, and grey on grey read as punctuation
 * rather than as a number.
 *
 * No dot between label and count, unlike the tabs: there the separator was
 * doing the work of telling one tab's count from the next tab's word, and
 * here the pill's own border already does it.
 *
 * Colour rather than opacity — a faded accent goes muddy, and the accent
 * carries on the dark selected pill as well as on the light ones.
 */
.c-filters__count {
  font-family: var(--mono);
  font-size: var(--size-micro);
  font-weight: 600;
  color: var(--accent);
}

/* c-form.css */
/*
 * One resource, as a form.
 *
 * Label beside field rather than above it, because a dozen stacked pairs
 * becomes a column of alternating text that reads as a list of headings. The
 * label column is fixed so every field starts at the same place and the eye
 * has one edge to run down.
 *
 * Everything is visible. An earlier version put body, author and published
 * behind a summary, on the grounds that most resources are a title, a blurb, a
 * link and some topics and only guides carry a body — which was true, and
 * still meant you could not tell whether a body existed without opening the
 * fold. The band is a label on a rule instead.
 */
.c-form {
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  overflow: hidden;
}

.c-form__pair {
  display: grid;
  grid-template-columns: 132px minmax(0, 1fr);
  gap: var(--space-3);
  align-items: start;
  padding: var(--space-3);
  border-bottom: 1px solid var(--line);
}

.c-form__label {
  padding-top: 8px;
  font-family: var(--mono);
  font-size: var(--size-label);
  color: var(--muted);
}

/* The box each field sits in. Deliberately no font here: the three of them
   want different ones, and setting a size that every rule below overrides is
   a line that looks like it does something. */
.c-form__input,
.c-form__select,
.c-form__area {
  width: 100%;
  padding: 8px 11px;
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  background: var(--surface);
  font: inherit;
  color: var(--ink);
}

.c-form__input:focus,
.c-form__select:focus,
.c-form__area:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

.c-form__input { font-size: var(--size-compact); }

.c-form__select { font-family: var(--mono); font-size: var(--size-label); }

/* Mono, because a body is markdown and markdown is easier to see the shape of
   when the characters line up. */
.c-form__area {
  min-height: 220px;
  font-family: var(--mono);
  font-size: var(--size-label);
  line-height: 1.55;
  resize: vertical;
}

.c-form__area--short { min-height: 68px; }

.c-form__note {
  margin: 6px 0 0;
  max-width: 62ch;
  font-size: var(--size-label);
  line-height: 1.5;
  color: var(--faint);
}

/* The word that carries the warning, in the body colour rather than bold on
   grey — at this size bold alone does not separate from the run of text. */
.c-form__note strong { font-weight: 500; color: var(--muted); }

.c-form__boxes { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-3); }

.c-form__box {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: var(--size-compact);
  color: var(--ink);
  cursor: pointer;
}

.c-form__file { font-size: var(--size-label); color: var(--muted); }

.c-form__shot {
  display: block;
  max-width: 190px;
  margin-bottom: var(--space-2);
  border: 1px solid var(--line);
  border-radius: var(--r);
}

/* A rule with a word on it, rather than a fold. These fields were behind a
   summary and the fold cost more than it saved: you cannot see whether a body
   exists without opening it, which is the thing you most want to know. */
.c-form__band {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
  font-family: var(--mono);
  font-size: var(--size-micro);
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--faint);
}


.c-form__do {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  background: var(--surface-2);
}

.c-form__save {
  padding: 9px 20px;
  border: 0;
  border-radius: var(--r);
  background: var(--ink);
  font-family: var(--mono);
  font-size: var(--size-label);
  font-weight: 600;
  color: var(--ground);
  cursor: pointer;
}

.c-form__save:hover { filter: brightness(1.25); }

.c-form__cancel { font-family: var(--mono); font-size: var(--size-label); color: var(--muted); }

/* Its own block, well below Save, because it is the one control on the page
   that cannot be taken back. */
.c-form__danger {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-5);
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--r);
}

.c-form__danger-what { font-size: var(--size-compact); color: var(--ink); }

.c-form__delete {
  margin-left: auto;
  flex: none;
  padding: 8px 16px;
  border: 1px solid var(--accent);
  border-radius: var(--r);
  background: var(--surface);
  font-family: var(--mono);
  font-size: var(--size-label);
  color: var(--accent-ink);
  cursor: pointer;
}

.c-form__delete:hover { background: var(--accent); color: var(--surface); }

@media (max-width: 700px) {
  .c-form__pair { grid-template-columns: minmax(0, 1fr); gap: var(--space-2); }
  .c-form__label { padding-top: 0; }
}

/* c-icon.css */
/*
 * The marks. Sized where they sit rather than here, and coloured by whatever
 * contains them — so the same icon works in an orange tile on a card and a
 * violet one in the feed without a variant for each.
 */
.c-icon { width: 100%; height: 100%; display: block; }

/* c-kinds.css */
/*
 * The four headline counts, in one box with rules between them rather than
 * four separate cards. Four cards read as four things; one box with dividers
 * reads as one summary, which is what it is.
 */
/* The dividers are a 1px GAP with the line colour showing through from
   behind, not four borders. One rule instead of two, and no double line where
   the outer edge meets an inner one. */
/* The reference sits these 22px below the pill above and gives each cell
   15px of vertical padding. Both are tighter here on purpose — a row of four
   numbers should read as one band, not four boxes. */
.c-kinds {
  margin-top: var(--space-3);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
}

.c-kinds__cell { padding: 12px 16px; background: var(--surface); }

.c-kinds__figure {
  font-family: var(--mono);
  font-size: var(--size-figure);
  font-weight: 600;
  line-height: 1.6;
  letter-spacing: -.02em;
}

/* "ms" after a number, at the size of the label under it rather than the
   figure it follows — a unit is not part of the measurement. */
.c-kinds__unit { margin-left: 2px; font-size: var(--size-small); font-weight: 400; color: var(--muted); }

.c-kinds__label {
  margin-top: 3px;
  font-family: var(--mono);
  font-size: var(--label-size);
  font-weight: var(--label-weight);
  letter-spacing: var(--label-track);
  text-transform: uppercase;
  color: var(--ink-2);
}

.c-kinds__note { margin-top: 2px; font-size: var(--size-small); color: var(--faint); }

@media (max-width: 760px) {
  .c-kinds { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .c-kinds__cell:nth-child(3) { border-left: 0; }
  .c-kinds__cell:nth-child(n+3) { border-top: 1px solid var(--line); }
}

/* c-latest.css */
/*
 * The foot of the sidebar: where to follow along, and how to send somebody.
 *
 * Sized against the reference. The heading was set at 14px, which wraps
 * "Refer a future fellow →" onto two lines and made the whole box half again
 * as tall as it should be — 132px against 88.
 */
.c-latest {
  padding: 0 20px 14px;
  margin-bottom: var(--space-2);
  border-bottom: 1px solid var(--line);
}

.c-latest__label {
  font-family: var(--mono);
  font-size: var(--label-size);
  font-weight: var(--label-weight);
  letter-spacing: var(--label-track);
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: var(--space-2);
}

.c-latest__links { display: flex; gap: 7px; }

/* A minimum rather than a width: "sub" needs more room than "in", and four of
   them still sit on one line at the sidebar's 232px. */
.c-latest__link {
  min-width: 30px;
  height: 30px;
  padding: 0 5px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  font-family: var(--mono);
  font-size: var(--size-small);
  font-weight: 600;
  color: var(--ink-2);
}

.c-latest__link:hover { background: var(--surface); text-decoration: none; }

.c-latest__refer {
  display: block;
  margin-top: var(--space-2);
  padding: 10px 11px;
  border: 1px dashed var(--line-2);
  border-radius: var(--r);
}

.c-latest__refer:hover { border-color: var(--accent); text-decoration: none; }

/* One line. That is the whole reason this is 11.5 and not 14. */
.c-latest__refer-head {
  display: block;
  font-family: var(--mono);
  font-size: var(--size-small);
  font-weight: 600;
  line-height: 1.35;
  white-space: nowrap;
}

.c-latest__refer-body {
  display: block;
  margin-top: 5px;
  font-size: var(--size-small);
  line-height: 1.4;
  color: var(--muted);
}

/* c-mini.css */
/*
 * Three small month grids, for looking at a quarter.
 *
 * A day carrying events gets a grey block behind its number and a dot per
 * event beneath it — orange for open to everyone, green for something
 * addressed to a group you are in, the same two colours the week grid uses.
 *
 * The block is doing most of the work. Dots alone are too fine to read as
 * density at this size; it is the filled squares that let you see that early
 * September is busy and late October is empty, which is the only question a
 * quarter raises that the other two views cannot answer.
 *
 * A day with something on it links to its week, where the events are legible.
 */
.c-mini-set {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}

.c-mini {
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  overflow: hidden;
}

/* A filled band across the top, not a rule under the words. */
.c-mini__name {
  padding: 9px var(--space-2);
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
  font-family: var(--mono);
  font-size: var(--size-small);
  font-weight: 600;
}

.c-mini__head, .c-mini__grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  padding: 0 var(--space-1);
}

.c-mini__head { padding-top: var(--space-1); }
.c-mini__grid { gap: 1px; padding-bottom: var(--space-2); }

.c-mini__letter {
  font-family: var(--mono);
  font-size: var(--size-micro);
  color: var(--faint);
  text-align: center;
  padding: 4px 0;
}

.c-mini__day {
  aspect-ratio: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  border-radius: 2px;
  font-family: var(--mono);
  font-size: var(--size-micro);
  color: var(--ink-2);
}

.c-mini__day--outside { color: var(--line-2); }

/* The grey block. Said as a modifier rather than as `a.c-mini__day` — what
   matters is that the day is busy, not which tag it happens to be. */
.c-mini__day--busy {
  background: var(--sunken);
  font-weight: 600;
  color: var(--ink);
}

.c-mini__day--busy:hover { background: var(--line); text-decoration: none; }

.c-mini__day--today {
  background: var(--ink);
  color: var(--ground);
  font-weight: 600;
}

.c-mini__day--today:hover { background: var(--ink-2); }

.c-mini__dots { display: flex; gap: 2px; height: 4px; align-items: center; }

.c-mini__dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--lime-ink);
}

.c-mini__dot--open { background: var(--accent); }

/* Against the dark square of today, the darker green disappears. */
.c-mini__day--today .c-mini__dot { background: var(--lime); }

@media (max-width: 900px) {
  .c-mini-set { grid-template-columns: minmax(0, 1fr); }
}

/* c-nav.css */
/*
 * The sidebar's list of destinations.
 *
 * The current page is a filled block rather than a tint, which is what the
 * prototype does and what makes it readable at a glance from across a desk.
 */
.c-nav { display: grid; gap: 1px; padding: 0 var(--space-2); }

.c-nav__item {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: 9px var(--space-2);
  border-radius: var(--r);
  color: var(--ink-2);
  /* Monospace at 13px, not bold sans at 15px. The sidebar is a list of
     destinations, not a set of headings, and setting it in the same face as
     the labels is most of why the reference reads calmer than this did. */
  font-family: var(--mono);
  font-size: var(--size-minor);
  font-weight: 400;
}

.c-nav__item:hover { background: rgba(1, 31, 46, .05); text-decoration: none; }

.c-nav__item[aria-current="page"] {
  background: var(--ink);
  color: var(--ground);
}

.c-nav__soon {
  margin-left: auto;
  padding: 2px 6px;
  border-radius: var(--r);
  background: var(--violet-wash);
  color: var(--violet-ink);
  font-family: var(--mono);
  font-size: var(--size-micro);
  letter-spacing: .1em;
}

/* Set apart from the pages above it: everything there is somewhere to look,
   this is somewhere to change things. The rule does the separating so the
   item itself can look like every other one. */
.c-nav__item--admin {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
}

/* c-net.css */
/*
 * Network search, before it exists — and the only dark surface in the hub.
 *
 * The whole page is the mock-up, edge to edge. Everything else here is warm
 * cream on a 1180px column; this is the one thing that is not built, and it
 * should not look like it is. A boxed preview with a heading above it and a
 * paragraph below reads as a page about a feature. This reads as the feature.
 *
 * The glow is ours rather than borrowed: the accent orange with a little of
 * the lime behind it, over the ink. Same building, different room.
 */
.c-net {
  position: relative;
  overflow: hidden;

  min-height: 100vh;

  /* Centred in the window rather than stacked from the top. With results on
     screen the group is short, and pinned to the top it left half a page of
     empty dark underneath it. */
  display: flex;
  flex-direction: column;
  justify-content: center;

  padding: var(--space-5) var(--space-4);
  background: #04141d;
  text-align: center;
}

.c-net::before {
  content: "";
  position: absolute;
  inset: -20% -10% auto -10%;
  height: 130%;
  pointer-events: none;
  background:
    radial-gradient(ellipse 46% 38% at 50% 30%, rgba(255, 77, 28, .26), transparent 70%),
    radial-gradient(ellipse 30% 24% at 32% 26%, rgba(156, 255, 110, .10), transparent 70%),
    radial-gradient(ellipse 60% 48% at 50% 36%, rgba(1, 31, 46, .9), transparent 75%);
}

.c-net > * { position: relative; }

.c-net__hi {
  margin: 0 0 30px;
  font-size: var(--size-display);
  font-weight: 400;
  letter-spacing: -.01em;
  color: rgba(255, 250, 245, .92);
}


/* ---- the field ---- */

.c-net__field {
  display: flex;
  align-items: center;
  gap: 14px;
  max-width: 860px;
  margin: 0 auto;
  padding: 16px 22px;
  border: 1px solid rgba(255, 250, 245, .16);
  border-radius: 999px;
  background: rgba(255, 250, 245, .06);
  text-align: left;
}

/* The magnifier only. Without the child combinator this also caught the arrow
   inside the send button and painted it at 45% — which read as a pink arrow on
   an orange disc, and looked like a colour choice rather than a bug. */
.c-net__field > svg { width: 19px; height: 19px; flex: none; color: rgba(255, 250, 245, .45); }

/* One line. A question long enough to be worth asking still has to sit in a
   pill, and wrapped it stops being one. */
.c-net__q {
  flex: 1;
  min-width: 0;
  font-size: var(--size-strong);
  color: rgba(255, 250, 245, .95);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The caret, because a still picture of a search box is a search box nobody
   has typed into. */
.c-net__q i {
  font-style: normal;
  margin-left: 2px;
  border-left: 2px solid var(--accent);
  animation: c-net-blink 1.1s step-end infinite;
}

@keyframes c-net-blink { 50% { border-color: transparent; } }

/* An SVG rather than an arrow character, because a glyph has whatever weight
   the font decided and this one needs to hold its own against a solid orange
   disc. White, not the dark of the page: the button is the one bright thing
   here and the mark on it should be the brightest part. */
.c-net__send {
  width: 32px;
  height: 32px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--accent);

  /* True white, not the page's warm cream — at #fffaf5 the arrow went soft
     against a colour this bright and read pink rather than white. */
  color: var(--surface);
}

.c-net__send svg { width: 17px; height: 17px; }


/* ---- what comes back ---- */

.c-net__out { max-width: 860px; margin: 34px auto 0; text-align: left; }

.c-net__n {
  margin-bottom: 12px;
  font-family: var(--mono);
  font-size: var(--size-small);
  letter-spacing: .06em;
  color: rgba(255, 250, 245, .42);
}

.c-net__hit { display: flex; align-items: center; gap: 15px; padding: 12px 4px; }
.c-net__hit + .c-net__hit { border-top: 1px solid rgba(255, 250, 245, .09); }

.c-net__face { width: 46px; height: 46px; flex: none; border-radius: 50%; object-fit: cover; }

.c-net__nm { display: block; font-size: var(--size-strong); color: rgba(255, 250, 245, .95); }
.c-net__ln { display: block; margin-top: 2px; font-size: var(--size-compact); color: rgba(255, 250, 245, .55); }

.c-net__tag {
  margin-left: auto;
  flex: none;
  padding: 3px 10px;
  border: 1px solid rgba(255, 250, 245, .2);
  border-radius: 999px;
  font-family: var(--mono);
  font-size: var(--size-micro);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(255, 250, 245, .5);
}

/* A mock this convincing has to say so. */
.c-net__foot {
  max-width: 860px;
  margin: 26px auto 0;
  text-align: left;
  font-family: var(--mono);
  font-size: var(--size-small);
  color: rgba(255, 250, 245, .36);
}

/* c-out.css */
/*
 * A link off this site: who they are, what they are, and an arrow.
 */
.c-out {
  display: block;
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  /* The spine, and the only colour on the card. Ink by default so a third
     link added later is neutral without having to opt out, and the accent
     stays something chosen rather than inherited. */
  border-left: 3px solid var(--ink);
  border-radius: var(--r);
  padding: 13px 15px;
}

.c-out--fund { border-left-color: var(--accent); }

/* The two of them sit together as one block, not as two rail entries. */
.c-out-pair { display: grid; gap: 8px; }

.c-out:hover { border-color: var(--line-2); text-decoration: none; }

.c-out__name {
  font-family: var(--mono);
  font-size: var(--size-compact);
  font-weight: 700;
  letter-spacing: .06em;
}

.c-out__what { margin-top: 3px; font-size: var(--size-small); line-height: 1.5; color: var(--muted); }

.c-out__arrow { position: absolute; top: var(--space-3); right: var(--space-3); color: var(--faint); font-size: var(--size-small); }

/* c-page.css */
/*
 * A page's opening: a small mono label, a title, and a line of explanation.
 */
.c-page {
  position: relative;
  margin-bottom: 14px;
}

/* The halftone field the prototype puts behind a page's opening. */
.c-page::after {
  content: "";
  position: absolute;
  top: -10px;
  right: 0;
  width: 190px;
  height: 90px;
  background-image: radial-gradient(var(--dot) 1px, transparent 1px);
  background-size: 9px 9px;
  -webkit-mask-image: linear-gradient(to left, #000, transparent);
  mask-image: linear-gradient(to left, #000, transparent);
  pointer-events: none;
}

.c-page__eyebrow {
  font-family: var(--mono);
  font-size: var(--label-size);
  font-weight: var(--label-weight);
  letter-spacing: var(--label-track);
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 4px;
}

.c-page__title { margin-bottom: 6px; }

/* Body size, not larger. A lede is set apart by being narrow and muted, not
   by being big — the reference does exactly this, and at 17px the measure
   came out 600px instead of 529px and the whole page read as shouting. */
.c-page__lede {
  color: var(--muted);
  max-width: 56ch;
  font-size: var(--size-body);
}

/* c-past.css */
/*
 * What already happened: a date rail down the left with a dashed line
 * threading through it, and a card with the poster on the right.
 *
 * The rail is what turns a stack of boxes into a timeline, and it costs one
 * pseudo-element.
 */
.c-past { display: grid; }

.c-past__row {
  position: relative;
  display: grid;
  grid-template-columns: 88px minmax(0, 1fr);
  gap: 18px;
  padding-bottom: 14px;
}

/* The thread, stopping at the last entry rather than running off the page. */
.c-past__row::before {
  content: "";
  position: absolute;
  left: 95px;
  top: 12px;
  bottom: 0;
  border-left: 1px dashed var(--line-2);
}

.c-past__row:last-child { padding-bottom: 0; }
.c-past__row:last-child::before { display: none; }

.c-past__when { position: relative; text-align: right; padding-top: 2px; }

.c-past__day { font-family: var(--mono); font-size: var(--size-compact); font-weight: 600; letter-spacing: -.01em; }
.c-past__weekday { font-family: var(--mono); font-size: var(--size-label); color: var(--faint); }

.c-past__dot {
  position: absolute;
  right: -10px;
  top: 8px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--line-2);
}

.c-past__card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 96px;
  gap: 16px;
  /* One value, not the reference's 14/14/15/16 — four numbers for a single
     decision is hand-tuning nobody can maintain, and this reads better a step
     tighter anyway. */
  padding: var(--space-2);
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
}

.c-past__card:hover { border-color: var(--line-2); text-decoration: none; }

.c-past__time { font-family: var(--mono); font-size: var(--size-small); color: var(--muted); }
.c-past__title { margin-top: 3px; font-size: var(--size-strong); font-weight: 600; line-height: 1.3; }

.c-past__meta {
  margin-top: 7px;
  display: grid;
  gap: 2px;
  font-size: var(--size-minor);
  line-height: 1.6;
  color: var(--muted);
}
.c-past__guests { color: var(--accent-ink); font-weight: 600; }
.c-past__checked { color: var(--faint); }

.c-past__cover {
  position: relative;
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: var(--r);
  background: var(--sunken);
}

.c-past__cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* Ours, with no cover: the title set small on the brand ground with the
   halftone behind it. The same disc the page's opening uses, so it reads as
   part of the design rather than as a picture that failed to load. */
.c-past__cover--bare {
  display: grid;
  align-items: end;
  padding: 9px;
  background-color: var(--ink);
  background-image: radial-gradient(rgba(255, 250, 245, .16) 1px, transparent 1px);
  background-size: 7px 7px;
}

.c-past__poster {
  font-family: var(--mono);
  font-size: var(--size-micro);
  line-height: 1.35;
  color: var(--ground);
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

@media (max-width: 760px) {
  .c-past__row { grid-template-columns: minmax(0, 1fr); }
  .c-past__row::before { display: none; }
  .c-past__when { text-align: left; }
  .c-past__dot { display: none; }
  .c-past__card { grid-template-columns: minmax(0, 1fr) 84px; }
}

/* c-person.css */
/*
 * Somebody in the directory. The photograph leads and everything else is
 * caption — a face is what you actually recognise a person by.
 */
.c-person {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  transition: border-color .12s, transform .12s;
}

.c-person:hover { border-color: var(--accent); transform: translateY(-1px); text-decoration: none; }

.c-person__face {
  display: block;
  aspect-ratio: 1;
  background: var(--surface-2) center / cover no-repeat;
  border-bottom: 1px solid var(--line);
}

.c-person__in { padding: 10px 11px 11px; flex: 1; display: flex; flex-direction: column; }

.c-person__name { font-size: var(--size-compact); font-weight: 600; line-height: 1.28; }

.c-person__org {
  margin-top: 3px;
  font-family: var(--mono);
  font-size: var(--size-micro);
  color: var(--accent-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.c-person__line { margin-top: var(--space-1); font-size: var(--size-minor); color: var(--muted); line-height: 1.35; flex: 1; }

.c-person__tag {
  align-self: flex-start;
  margin-top: var(--space-2);
  padding: 2px 6px;
  border-radius: var(--r);
  background: var(--sunken);
  color: var(--muted);
  font-family: var(--mono);
  font-size: var(--size-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
}

/* c-policies.css */
/*
 * The written policies, and which of them exist yet. A row that is still
 * being drafted says so rather than being hidden — people ask for these, and
 * "not written yet" is a more useful answer than silence.
 */
.c-policies { display: grid; }

.c-policies__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line);
  border-bottom: 0;
  background: var(--surface);
  font-size: var(--size-compact);
}

.c-policies__row:first-child { border-radius: var(--r) var(--r) 0 0; }
.c-policies__row:last-child { border-bottom: 1px solid var(--line); border-radius: 0 0 var(--r) var(--r); }
.c-policies__row:hover { background: var(--surface-2); text-decoration: none; }

.c-policies__state {
  font-family: var(--mono);
  font-size: var(--size-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--faint);
  white-space: nowrap;
}

.c-policies__state--ready { color: var(--lime-ink); }

/* c-poster.css */
/*
 * An event in the rail: a square cover on the left, the words beside it.
 *
 * Not a wide poster with text underneath. Luma's covers are square-ish and a
 * 16:9 crop slices the type off them, which is what the reference discovered
 * and worked around — and beside the text they stack into a rail four deep
 * where the tall version fits two.
 */
.c-poster {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  align-items: stretch;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
}

.c-poster:hover { border-color: var(--line-2); text-decoration: none; }

.c-poster__cover { position: relative; overflow: hidden; background: var(--sunken); }
.c-poster__cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* Without a cover the square would be a grey hole, so the words take the row. */
.c-poster--bare { grid-template-columns: minmax(0, 1fr); }

.c-poster__body {
  padding: 10px var(--space-2);
  min-height: 96px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.c-poster__when {
  font-family: var(--mono);
  font-size: var(--size-label);
  line-height: 1.6;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--accent-ink);
}

/* Two lines at most. The cover is a 96px square and the body is built to match
   it, so a third line would push the card past its own picture — and the two
   longest titles Encode has run, "Machines in the Wild Demo Night: AI x
   Hardware for Resilience" and the Unblock salon, both fit in two. */
.c-poster__title {
  margin-top: 2px;
  font-size: var(--size-compact);
  font-weight: 500;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* One line, whatever the venue is called. The count is the number somebody is
   scanning the rail for, so it never gives way; the venue does, and the row
   keeps every card the same height. */
.c-poster__meta {
  margin-top: 3px;
  display: flex;
  align-items: baseline;
  gap: 5px;
  min-width: 0;
  font-size: var(--size-minor);
  line-height: 1.45;
  color: var(--muted);
}

.c-poster__where { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The number is the point. Three hundred people came to a salon about wet-lab
   AI; it should not be the same grey as the street it happened on. Accent and
   semibold, matching c-past exactly — the two lists show the same fact and
   should not have invented two ways of showing it. */
.c-poster__going {
  flex: none;
  white-space: nowrap;
  font-weight: 600;
  color: var(--accent-ink);
}

/* The separator belongs to the pair, not to either half — so it appears only
   when there is something on both sides of it. */
.c-poster__where + .c-poster__going::before { content: "·"; margin-right: 5px; color: var(--line-2); }

.c-poster--quiet .c-poster__when { color: var(--muted); }

/* c-prose.css */
/*
 * Rendered Markdown. The only place in this codebase where HTML is written by
 * something other than a template, so it is styled by one wrapper rather than
 * by classes the renderer would have to know about.
 */
/* Always follows a heading or a photograph on the two pages that use it. */
.c-prose {
  margin-top: var(--space-4);
  max-width: var(--measure);
  font-size: var(--size-strong);
  line-height: 1.6;
}

.c-prose h2 { margin: var(--space-5) 0 var(--space-2); font-size: var(--size-title); }
.c-prose h3 { margin: var(--space-4) 0 var(--space-2); font-size: var(--size-strong); }
.c-prose h4 { margin: var(--space-4) 0 var(--space-1); font-size: var(--size-body); }

.c-prose p { margin: 0 0 var(--space-3); }
.c-prose ul, .c-prose ol { margin: 0 0 var(--space-3); padding-left: 1.2em; }
.c-prose ul { list-style: disc; }
.c-prose ol { list-style: decimal; }
.c-prose li { margin-bottom: var(--space-1); }

.c-prose a { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 2px; }

.c-prose code {
  font-family: var(--mono);
  font-size: .88em;
  background: var(--sunken);
  padding: 1px 5px;
  border-radius: 2px;
}

.c-prose hr { margin: var(--space-4) 0; }

.c-prose__none { color: var(--faint); font-size: var(--size-body); }

/* c-rail.css */
/*
 * A block in the right-hand column: a label, then whatever it introduces.
 */
/* A label, and optionally something small on the right of it. */
.c-rail__label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  font-family: var(--mono);
  font-size: var(--label-size);
  /* Lighter than an eyebrow. A rail head introduces a column rather than a
     page, and the reference makes exactly that distinction. */
  font-weight: 400;
  letter-spacing: var(--label-track);
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: var(--space-1);
}

.c-rail__all { font-size: var(--size-label); letter-spacing: .1em; color: var(--accent-ink); }

/* Several rail blocks are a heading over a stack of things. */
.c-rail__stack { display: grid; gap: var(--space-2); }

.c-rail__box {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: var(--space-3);
  font-size: var(--size-compact);
  color: var(--muted);
}

/* c-range.css */
/*
 * The bar above the calendar: which week you are looking at, how to move,
 * and how wide a view to take.
 */
.c-range {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
  flex-wrap: wrap;
}

.c-range__step {
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: var(--r);
  color: var(--muted);
  font-size: var(--size-body);
}

.c-range__step:hover { background: var(--surface); color: var(--ink); text-decoration: none; }

.c-range__label {
  font-family: var(--mono);
  font-size: var(--size-compact);
  font-weight: 600;
  letter-spacing: normal;
  min-width: 15ch;
}

.c-range__views { display: flex; gap: var(--space-1); margin-left: auto; }

.c-range__view {
  padding: 6px var(--space-3);
  border: 1px solid var(--line-2);
  border-radius: 999px;
  font-family: var(--mono);
  font-size: var(--size-small);
  color: var(--ink-2);
}

.c-range__view:hover { background: var(--surface); text-decoration: none; }

.c-range__view[aria-current="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--ground);
}

/* c-rules.css */
/*
 * House rules: one per row, each its own box, so none of them reads as a
 * footnote to the one above it.
 */
.c-rules { display: grid; }

.c-rules__item {
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-bottom: 0;
  background: var(--surface);
  font-size: var(--size-body);
}

.c-rules__item:first-child { border-radius: var(--r) var(--r) 0 0; }
.c-rules__item:last-child { border-bottom: 1px solid var(--line); border-radius: 0 0 var(--r) var(--r); }

/* c-section.css */
/*
 * A heading with something small on the right of it.
 */
.c-section {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin: var(--space-5) 0 var(--space-3);
}

/* letter-spacing reset: base.css tightens every heading by -.01em, which is
   right at 28px and wrong at 15. */
.c-section__title {
  font-family: var(--mono);
  font-size: var(--size-body);
  font-weight: 600;
  letter-spacing: normal;
}

.c-section__aside {
  font-family: var(--mono);
  font-size: var(--label-size);
  font-weight: var(--label-weight);
  letter-spacing: var(--label-track);
  text-transform: uppercase;
  color: var(--faint);
}

/* c-set.css */
/*
 * Settings: rows in a box, the same box the rest of the hub uses for a list of
 * facts. Deliberately not a form layout with labels above fields and a save
 * bar at the bottom — each section here does one thing and submits on its own,
 * so there is never a question of what a button is about to save.
 */
.c-set {
  margin-top: var(--space-2);
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
}

.c-set__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 11px var(--space-2) 12px;
}

.c-set__row + .c-set__row { border-top: 1px solid var(--line); }

/* A label and its field on one line: the page is a column of short questions,
   and stacking them doubles its height for nothing. */
.c-set__row--field { justify-content: space-between; }
.c-set__row--do { gap: var(--space-2); }

/* Every action ends at the same right edge, whatever the thing on the left is
   called. Otherwise a column of Revoke buttons steps in and out with the
   length of each token's name. */
.c-set__row > form { margin-left: auto; }

/* The one row with a field in it: the field takes the space so the button
   lands on that same edge as the Revokes above it. */
.c-set__row--do .c-set__input { max-width: none; }

.c-set__title { font-size: var(--size-compact); font-weight: 500; }
.c-set__note { font-size: var(--size-small); color: var(--faint); }

.c-set__label {
  font-family: var(--mono);
  font-size: var(--size-label);
  letter-spacing: .06em;
  color: var(--muted);
}

.c-set__input {
  flex: 1;
  max-width: 280px;
  padding: 6px 9px;
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  background: var(--ground);
  font-family: inherit;
  font-size: var(--size-compact);
  color: var(--ink);
}

.c-set__input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

.c-set__go {
  padding: 7px var(--space-3);
  border: 0;
  border-radius: var(--r);
  background: var(--ink);
  color: var(--ground);
  font-family: var(--mono);
  font-size: var(--size-compact);
  font-weight: 600;
  cursor: pointer;
}

.c-set__go:hover { background: var(--accent); }

/* Signing out is not the thing you came here to do. */
.c-set__go--quiet { background: transparent; border: 1px solid var(--line-2); color: var(--ink); }
.c-set__go--quiet:hover { background: var(--surface-2); color: var(--accent-ink); }

.c-set__revoke {
  padding: 4px 10px;
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  background: transparent;
  font-family: var(--mono);
  font-size: var(--size-small);
  color: var(--muted);
  cursor: pointer;
}

.c-set__revoke:hover { border-color: var(--accent); color: var(--accent-ink); }

.c-set__badge {
  margin-left: auto;
  font-family: var(--mono);
  font-size: var(--size-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--faint);
}

/* What just happened, above the thing it happened to. */
.c-set__said {
  margin-top: var(--space-2);
  font-size: var(--size-compact);
}

.c-set__said--good { color: var(--lime-ink); }
.c-set__said--bad { color: var(--accent-ink); }

/* A token, once. Loud because there is no second chance to read it — only a
   sha256 of it is stored, so this render is the only place it exists. */
.c-set__minted {
  margin-top: var(--space-2);
  padding: var(--space-2);
  border: 1px solid var(--accent);
  border-radius: var(--r);
  background: var(--accent-wash);
}

.c-set__token {
  display: block;
  margin-top: 6px;
  font-family: var(--mono);
  font-size: var(--size-compact);
  color: var(--ink);
  word-break: break-all;
  user-select: all;
}

/* c-soon.css */
/*
 * Something that does not exist yet, said plainly rather than hidden.
 */
.c-soon {
  position: relative;
  overflow: hidden;
  padding: var(--space-3);
  border: 1px solid var(--violet);
  border-radius: var(--r);
  background: var(--violet-wash);
}

.c-soon::after {
  content: "";
  position: absolute;
  top: -20px;
  right: -20px;
  width: 140px;
  height: 110px;
  background-image: radial-gradient(rgba(122, 58, 150, .22) 1px, transparent 1px);
  background-size: 9px 9px;
  -webkit-mask-image: radial-gradient(circle at 70% 30%, #000, transparent 72%);
  mask-image: radial-gradient(circle at 70% 30%, #000, transparent 72%);
}

.c-soon__head { font-family: var(--mono); font-size: var(--size-body); font-weight: 600; color: var(--violet-ink); }
.c-soon__body { margin-top: var(--space-2); font-size: var(--size-compact); color: var(--muted); line-height: 1.5; }

/* c-strip.css */
/*
 * A row of photographs with their captions laid over the bottom.
 */
.c-strip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-2); }

.c-strip__item {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--r);
  background: var(--sunken);
}

.c-strip__item img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.c-strip__caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 22px var(--space-2) var(--space-1);
  font-size: var(--size-small);
  color: #fff;
  background: linear-gradient(to top, rgba(1, 31, 46, .78), rgba(1, 31, 46, 0));
}

@media (max-width: 760px) { .c-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* c-tabs.css */
/*
 * Which set of people you are looking at.
 *
 * One object rather than six: the tabs sit inside a single bordered track, so
 * the bar reads as a switch with a position rather than as a row of loose
 * words with one of them highlighted. That matters more the more tabs there
 * are, and there are six now.
 *
 * Shared with the office page and the admin screens. Those have no counts, so
 * the separator below only appears where a count does.
 */
.c-tabs {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0;
  align-items: center;
  margin: var(--space-4) 0 var(--space-3);
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
}

.c-tabs__tab {
  display: inline-flex;
  align-items: center;
  padding: 6px 15px;
  border-radius: 999px;
  font-size: var(--size-compact);
  color: var(--muted);
  white-space: nowrap;
}

.c-tabs__tab:hover { color: var(--ink); text-decoration: none; }

.c-tabs__tab[aria-current="true"] { background: var(--ink); color: var(--ground); }

/* A separator, so the number is a second fact rather than something stuck to
   the end of the word — "Cohort 2 13" reads as a typo, "Cohort 2 · 13" does
   not. The dot is drawn here rather than typed into the template so a tab
   without a count does not carry a stray one. */
.c-tabs__n {
  margin-left: 7px;
  font-size: var(--size-minor);
  color: var(--accent);
}

/* The dot stays grey while the number is the accent — colouring both would
   make the separator argue with the thing it is separating. It needs a second
   value on the selected tab, where grey on near-black is unreadable; the
   number does not, because the accent carries on either ground. */
.c-tabs__n::before {
  content: "\00b7";
  margin-right: 7px;
  color: var(--faint);
}

.c-tabs__tab[aria-current="true"] .c-tabs__n::before { color: rgba(255, 250, 245, .4); }

/* c-tally.css */
/*
 * A ranked list with a bar behind the number.
 *
 * The same shape serves pages, people and errors, because they are the same
 * question three times: what, how often, and when last. Three components would
 * have been three sets of the same padding.
 */
.c-tally {
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  overflow: hidden;
}

.c-tally__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 9px var(--space-3);
  border-bottom: 1px solid var(--line);
}

.c-tally__row:last-child { border-bottom: 0; }
.c-tally__row:hover { background: var(--surface-2); }

.c-tally__what {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  font-family: var(--mono);
  font-size: var(--size-minor);
  color: var(--ink);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.c-tally__tag {
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--violet-wash);
  font-size: var(--size-micro);
  color: var(--violet-ink);
}

/* Proportion, not a second number. The count is already at the end of the row;
   this is only there so the shape of the list is readable without reading it. */
.c-tally__meter {
  flex: none;
  width: 180px;
  height: 5px;
  border-radius: 999px;
  background: var(--surface-2);
  overflow: hidden;
}

.c-tally__meter span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
}

.c-tally__when {
  flex: none;
  font-family: var(--mono);
  font-size: var(--size-micro);
  color: var(--faint);
}

.c-tally__n {
  flex: none;
  width: 52px;
  text-align: right;
  font-family: var(--mono);
  font-size: var(--size-minor);
  color: var(--muted);
}

.c-tally__code {
  flex: none;
  width: 34px;
  font-family: var(--mono);
  font-size: var(--size-micro);
  color: var(--muted);
}

.c-tally__code--bad { color: var(--accent-ink); }
.c-tally__code--meh { color: var(--faint); }

.c-tally__none {
  padding: var(--space-4) var(--space-3);
  font-family: var(--mono);
  font-size: var(--size-compact);
  color: var(--faint);
  text-align: center;
}

@media (max-width: 800px) {
  .c-tally__meter { display: none; }
}

/* c-tour.css */
/*
 * The one call to action on the home page.
 */
.c-tour {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px 5px 8px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  color: var(--accent-ink);
  font-family: var(--mono);
  font-size: var(--size-small);
  line-height: 1.6;
}

.c-tour:hover { background: var(--accent-wash); text-decoration: none; }

.c-tour__play {
  width: 19px;
  height: 19px;
  flex: none;
  border: 1px solid var(--accent);
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: var(--size-micro);
}

/* c-week.css */
/*
 * The calendar itself: a column per day, with each event as a tinted block.
 *
 * Two colours, and they mean something specific. Orange is open to everyone
 * — no group named on it. Green is addressed to a group you are in. Nothing
 * you cannot attend appears at all, so the grid is honestly your week rather
 * than the fellowship's.
 */
.c-week {
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
  background: var(--surface);
}

.c-week__head, .c-week__body { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }

.c-week__head { border-bottom: 1px solid var(--line); background: var(--surface-2); }

.c-week__day { padding: var(--space-2) var(--space-2) var(--space-3); border-left: 1px solid var(--line); }
.c-week__day:first-child { border-left: 0; }

.c-week__name {
  font-family: var(--mono);
  font-size: var(--size-micro);
  font-weight: 700;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--faint);
}

.c-week__num {
  margin-top: 2px;
  font-family: var(--mono);
  font-size: var(--size-strong);
  font-weight: 900;
  letter-spacing: normal;
}

.c-week__day--today .c-week__num { color: var(--accent-ink); }

.c-week__col {
  /* Tall enough that an empty week still reads as a calendar, short enough
     that six empty columns beside one busy Friday are not a page of nothing. */
  min-height: 160px;
  /* Tight, because the column is only about 115px wide and every pixel of
     padding is a pixel the title does not get. */
  padding: var(--space-1);
  border-left: 1px solid var(--line);
  display: grid;
  /* Declared, because an implicit track is `auto` and sizes to max-content —
     which let a card with a long unbroken word grow 8px wider than its own
     column and sit over the next day's border. */
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  gap: var(--space-1);
}

.c-week__col:first-child { border-left: 0; }

.c-week__none {
  color: var(--line-2);
  font-family: var(--mono);
  font-size: var(--size-minor);
  text-align: center;
  padding-top: var(--space-2);
}

.c-week__event {
  display: block;
  padding: 6px 7px;
  border-radius: var(--r);
  background: var(--lime-wash);
  color: var(--lime-ink);
}

.c-week__event:hover { text-decoration: none; filter: brightness(.97); }

.c-week__event--open { background: var(--accent-wash); color: var(--accent-ink); }

/* Three lines, not one paragraph. These are spans inside an <a>, so without
   this they flow inline and the time, the title and the place run together —
   which is what made a 97px block 160px tall. */
.c-week__at {
  display: block;
  font-family: var(--mono);
  font-size: var(--size-label);
  font-weight: 600;
}

/* Three lines at most. A title long enough to need a fourth is a title
   nobody reads off a calendar anyway, and the block it sits in is the tallest
   thing in the column. The full one is the link's own title attribute and the
   heading of the page it opens. */
.c-week__title {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-top: 2px;
  font-size: var(--size-small);
  font-weight: 500;
  line-height: 1.3;
  color: var(--ink);
}

.c-week__where {
  display: block;
  margin-top: 3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: var(--size-label);
  line-height: 1.35;
}

.c-week__legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-3);
  font-size: var(--size-compact);
  color: var(--muted);
}

.c-week__key { display: inline-flex; align-items: center; gap: var(--space-2); }

.c-week__swatch {
  width: 13px;
  height: 13px;
  border-radius: 2px;
  border: 1px solid var(--lime-ink);
  background: var(--lime-wash);
}

.c-week__swatch--open { border-color: var(--accent); background: var(--accent-wash); }

@media (max-width: 900px) {
  .c-week__head { display: none; }
  .c-week__body { grid-template-columns: minmax(0, 1fr); }
  .c-week__col { border-left: 0; border-top: 1px solid var(--line); min-height: 0; }
  .c-week__col:first-child { border-top: 0; }
}

/* c-who.css */
/*
 * Who you are signed in as, at the foot of the sidebar — and the way into
 * settings, which is the only page behind it.
 */
.c-who {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3) 0;
  border-top: 1px solid var(--line);
  margin: 0 var(--space-2);
  padding-top: var(--space-3);
}

.c-who:hover { text-decoration: none; }
.c-who:hover .c-who__name { color: var(--accent-ink); }
.c-who:hover .c-who__go { color: var(--accent); }
.c-who--here .c-who__name { color: var(--accent-ink); }

/* A chevron rather than a label: the sidebar is 232px and "Settings" beside a
   name that may already be two words does not fit. */
.c-who__go { margin-left: auto; color: var(--line-2); font-size: var(--size-body); }

.c-who__face {
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: 50%;
  background: var(--accent-wash);
  color: var(--accent-ink);
  display: grid;
  place-items: center;
  font-family: var(--mono);
  font-size: var(--size-label);
  font-weight: 600;
}

.c-who__name { font-size: var(--size-compact); font-weight: 600; line-height: 1.2; }

.c-who__meta {
  font-family: var(--mono);
  font-size: var(--size-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--faint);
}

/* c-who2.css */
/*
 * The accounts list.
 *
 * `c-who` was taken by the person in the sidebar, and this is a different
 * thing — a row per account with what they can see and when they were last
 * here. Suspended rows are dimmed AND labelled: dimming alone is a state
 * somebody has to learn, and a word is not.
 */
.c-who2 {
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  overflow: hidden;
}

.c-who2__top {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
}

.c-who2__count {
  flex: 1;
  font-family: var(--mono);
  font-size: var(--size-label);
  color: var(--faint);
}

.c-who2__new {
  padding: 0 14px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  border-radius: var(--r);
  background: var(--ink);
  font-family: var(--mono);
  font-size: var(--size-label);
  color: var(--ground);
}

.c-who2__new:hover { text-decoration: none; filter: brightness(1.25); }

.c-who2__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-1) var(--space-3);
  border-bottom: 1px solid var(--line);
}

.c-who2__row:last-child { border-bottom: 0; }
.c-who2__row:hover { background: var(--surface-2); }

/* Dimmed as well as labelled. Two signals, because "this account is off" is
   the one fact on the row that changes what everything else means. */
.c-who2__row--off { opacity: .55; }

.c-who2__face {
  width: 38px;
  height: 38px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--surface-2);
  font-family: var(--mono);
  font-size: var(--size-label);
  color: var(--muted);
}

.c-who2__in { flex: 1; min-width: 0; }
.c-who2__in:hover { text-decoration: none; }
.c-who2__in:hover .c-who2__name { color: var(--accent-ink); }

.c-who2__name {
  display: block;
  font-size: var(--size-compact);
  color: var(--ink);
}

.c-who2__mail {
  display: block;
  margin-top: 1px;
  font-family: var(--mono);
  font-size: var(--size-micro);
  color: var(--muted);
}

.c-who2__tag {
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--violet-wash);
  font-family: var(--mono);
  font-size: var(--size-micro);
  color: var(--violet-ink);
}

.c-who2__tag--off { background: var(--accent-wash); color: var(--accent-ink); }

.c-who2__standing {
  flex: none;
  width: 210px;
  font-family: var(--mono);
  font-size: var(--size-micro);
  color: var(--muted);
}

.c-who2__seen {
  flex: none;
  width: 140px;
  font-family: var(--mono);
  font-size: var(--size-micro);
  color: var(--faint);
}

.c-who2__flip {
  flex: none;
  width: 84px;
  height: 28px;
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  background: var(--surface);
  font-family: var(--mono);
  font-size: var(--size-label);
  color: var(--ink);
  cursor: pointer;
}

.c-who2__flip:hover:enabled { border-color: var(--ink); }

/* Your own row. The button is there so the column does not have a hole in it,
   and refused so the hole is explained rather than merely absent. */
.c-who2__flip:disabled { opacity: .35; cursor: not-allowed; }

@media (max-width: 1000px) {
  .c-who2__row { flex-wrap: wrap; }
  .c-who2__in { flex: 1 1 100%; }
  .c-who2__standing, .c-who2__seen { width: auto; }
}
