/*
 * siftbox. One hand-written stylesheet: ten colours, two rule weights, no
 * radius and no shadow, which maps to custom properties far better than to
 * utility classes.
 *
 * Two typefaces carry the whole system, and one rule decides between them:
 * Archivo is never uppercase, JetBrains Mono is always uppercase. Anything
 * set in mono therefore also carries `text-transform: uppercase` — the
 * locale files hold sentence case, so translations stay readable and dynamic
 * content (sender names, subjects) obeys the same rule as fixed copy.
 *
 * Spacing is deliberately not tokenised. The design specifies seventeen
 * exact steps used literally per element, and a --space-11 standing for 44px
 * would help nobody read this file.
 *
 * Breakpoints are 720px and 1024px. Below 720px is the mobile treatment.
 */

:root {
  --ink: #0a0a0a;
  --paper: #ffffff;
  --body: #4a4a4a;
  --mute: #6a6a6a;
  --read: #9a9a9a;
  --rule: #e2e2e2;
  --blue: #1f1fe0;
  --hover: #f4f4f7;
  --fallback: #c4c4c4;
  --landing-paper: #f6f6f3;

  --sans: "Archivo", system-ui, -apple-system, "Segoe UI", Helvetica, Arial,
    sans-serif;
  --mono: "JetBrains Mono", ui-monospace, Menlo, monospace;

  --gutter: 24px;
  --frame: 1240px;
  --measure: 680px;
}

@media (min-width: 720px) {
  :root {
    --gutter: 56px;
  }
}

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
}

/* Negative tracking scales with size — the bigger the type, the tighter — so
   each heading sets its own. This is the floor for anything that doesn't. */
h1,
h2,
h3,
h4 {
  letter-spacing: -0.02em;
  text-wrap: pretty;
}

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

/* Mark ------------------------------------------------------------------- */

.mark {
  display: block;
  flex: none;
}

.mark__square {
  fill: var(--blue);
}

/* Mark and wordmark on one baseline, at roughly the same optical size. The
   mark is rendered at its desktop size and scaled by CSS below 720px, so its
   stroke weight is the one `mark_stroke_width` picked for that size. */
.lockup {
  display: flex;
  align-items: center;
  gap: 12px;
}

.lockup__wordmark {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.035em;
  color: var(--ink);
}

@media (max-width: 719px) {
  .lockup {
    gap: 10px;
  }

  .lockup .mark {
    width: 20px;
    height: 20px;
  }

  .lockup__wordmark {
    font-size: 22px;
  }
}

/* Masthead ---------------------------------------------------------------- */

/* The nameplate and the line naming the page: brand and links on one ruled
   band, the page's own line on a second. Every screen behind the gate wears
   it, the archive of originals included — it took this block's name over from
   the feed's old header when read state took the filter bar away.

   It wraps because the nav grew a third link. Nameplate and three mono links
   come to more than a 320px screen has once the gutters are paid for, and
   without this the page scrolls sideways rather than the links dropping to a
   second line. The gap does double duty as the row gap when they do. */
.masthead__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 24px var(--gutter) 20px;
  border-bottom: 2px solid var(--ink);
}

/* The nameplate is a link on every edition page — the way back to the day's
   briefing. It carries the mark, which is drawn in currentColor, so the link
   colour has to be put back to ink or the brackets turn blue. */
.masthead__home {
  color: var(--ink);
  text-decoration: none;
}

.masthead__nav {
  display: flex;
  align-items: center;
  gap: 14px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.masthead__link {
  color: var(--mute);
  text-decoration: none;
}

.masthead__link:hover {
  color: var(--ink);
}

/* An h1 set at 10px. What an edition is called is its number and the day it
   covers, and the line carries them the way a dateline does — mono, which
   also puts back the positive tracking every other heading gives up. */
.masthead__line {
  margin: 0;
  padding: 14px var(--gutter);
  border-bottom: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

@media (min-width: 720px) {
  .masthead__bar {
    padding: 28px var(--gutter);
  }

  .masthead__nav {
    gap: 26px;
    font-size: 11px;
  }

  .masthead__line {
    padding: 16px var(--gutter);
    font-size: 11px;
  }
}

/* Pen notice -------------------------------------------------------------- */

/* App chrome, and it has to look like nothing else on the page: a mono band
   the full width of the screen, sitting in the masthead's register rather
   than the edition's measure, so it can never be mistaken for a story. Blue
   because it is the one thing here to act on, and the arrow is direction
   rather than copy, so it is drawn here and not translated.

   One rule below and the masthead's rule above — the two it sits between. A
   border-top of its own would sit flush against that one and read as a single
   2px rule, which is the weight a section heading takes and this is not one. */
.badge {
  display: block;
  padding: 13px var(--gutter);
  border-bottom: 1px solid var(--rule);
  color: var(--blue);
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
}

.badge::after {
  content: "\00a0\00a0→";
}

.badge:hover {
  background: var(--hover);
}

@media (min-width: 720px) {
  .badge {
    padding: 15px var(--gutter);
    font-size: 11px;
  }
}

/* Edition ----------------------------------------------------------------- */

/* One column at the reading measure, centred the way the reader's article is.
   The section heading takes the 2px rule and the stories under it take the
   1px one, which is the whole of the hierarchy on the page. */
.edition {
  padding: 0 var(--gutter) 48px;
}

.edition__section {
  max-width: var(--measure);
  margin: 0 auto;
  padding-top: 32px;
}

.edition__heading {
  margin: 0;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--ink);
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

@media (min-width: 720px) {
  .edition {
    padding-bottom: 96px;
  }

  .edition__section {
    padding-top: 56px;
  }

  .edition__heading {
    padding-bottom: 10px;
    font-size: 11px;
  }
}

/* Story ------------------------------------------------------------------- */

/* A lead story, a Briefly line and a reading list entry are one shape at
   three lengths, so the type scale is all that separates them and it hangs
   off the section rather than off a partial each. */
.story {
  padding: 24px 0 28px;
  border-bottom: 1px solid var(--rule);
}

.story__headline {
  margin: 0;
  font-size: 22px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.025em;
  text-wrap: pretty;
}

/* pre-line rather than a paragraph per line: the editor's copy arrives as
   text and stays text, so a break in it is honoured by CSS reading the string
   and never by markup assembled out of what a model wrote. */
.story__body {
  margin: 12px 0 0;
  font-size: 17px;
  line-height: 1.6;
  color: var(--body);
  white-space: pre-line;
  text-wrap: pretty;
}

.edition__section--lead .story__headline {
  font-size: 28px;
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.03em;
}

.edition__section--briefly .story__headline {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.edition__section--briefly .story__body {
  font-size: 16px;
}

/* Where the claim came from, and the one place it can be checked. */
.story__sources {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
  margin-top: 16px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.story__sources-label {
  color: var(--mute);
}

.story__list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.story__source {
  color: var(--mute);
}

/* The separator belongs to the layout rather than to the copy, so it is drawn
   here — the same slash the feed's mono line draws between its fields. */
.story__source:not(:last-child)::after {
  content: "\00a0/";
}

.story__link {
  color: var(--blue);
  text-decoration: none;
}

.story__link:hover {
  color: var(--ink);
}

@media (min-width: 720px) {
  .story {
    padding: 32px 0 36px;
  }

  .story__headline {
    font-size: 26px;
    letter-spacing: -0.03em;
  }

  .story__body {
    margin-top: 14px;
    font-size: 19px;
    line-height: 1.65;
  }

  .edition__section--lead .story__headline {
    font-size: 36px;
    line-height: 1.08;
    letter-spacing: -0.035em;
  }

  .edition__section--briefly .story__headline {
    font-size: 18px;
  }

  .edition__section--briefly .story__body {
    font-size: 17px;
  }

  .story__sources {
    gap: 14px;
    margin-top: 20px;
    font-size: 11px;
  }

  .story__list {
    gap: 14px;
  }
}

/* Archive of editions ----------------------------------------------------- */

/* Every edition there has been, at the same measure the edition itself is set
   at. One row per day: the day covered carries the row because it is what the
   list is ordered by, and the number rides beside it in mono at the index's
   own scale. No blue on the number: the whole row is the link, and a second
   thing in the accent colour would read as a second thing to click. */
.archive {
  padding: 0 var(--gutter) 48px;
}

.archive__caption {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  max-width: var(--measure);
  margin: 0 auto;
  padding: 32px 0 8px;
  border-bottom: 2px solid var(--ink);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.archive__order {
  color: var(--mute);
}

.archive__list {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 0;
  list-style: none;
}

.archive__link {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: baseline;
  column-gap: 14px;
  padding: 18px 0;
  border-bottom: 1px solid var(--rule);
  text-decoration: none;
  color: inherit;
}

.archive__number {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--mute);
}

.archive__date {
  font-size: 18px;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.archive__empty {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 48px 0;
  font-size: 17px;
  line-height: 1.65;
  color: var(--body);
  text-wrap: pretty;
}

@media (min-width: 720px) {
  .archive {
    padding-bottom: 96px;
  }

  .archive__caption {
    padding: 56px 0 10px;
    font-size: 11px;
  }

  /* The row grows a hover tint and the padding to hold it, as the feed's rows
     do above the same breakpoint and for the same reason: below it there is
     no pointer to answer. */
  .archive__link {
    grid-template-columns: 72px 1fr;
    column-gap: 24px;
    padding: 22px 14px;
    margin: 0 -14px;
  }

  .archive__link:hover {
    background: var(--hover);
  }

  .archive__number {
    font-size: 12px;
    letter-spacing: 0;
  }

  .archive__date {
    font-size: 23px;
  }

  .archive__empty {
    padding: 72px 0;
  }
}

/* Subscriptions ----------------------------------------------------------- */

/* The pen and the two nets around it, at the measure every page behind the
   gate is set to. Three sections in one shape, built the way the edition's
   are: the heading takes the 2px rule, the rows under it take the 1px one,
   and nothing else separates them. */
.pen {
  padding: 0 var(--gutter) 48px;
}

.pen__section {
  max-width: var(--measure);
  margin: 0 auto;
  padding-top: 32px;
}

.pen__heading {
  margin: 0;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--ink);
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.pen__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The rule belongs to the item and the grid to the line inside it, so a row
   that is a link and a row that is not sit on exactly the same rails and the
   rule keeps to the measure whatever the line does with its own margins. */
.pen__item {
  border-bottom: 1px solid var(--rule);
}

.pen__line {
  display: grid;
  grid-template-columns: 1fr;
  row-gap: 4px;
  padding: 16px 0;
  color: inherit;
  text-decoration: none;
}

.pen__sender {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--mute);
}

.pen__subject {
  font-size: 17px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-wrap: pretty;
}

/* The one thing on this page that ages. How long a confirmation has been
   waiting is what the reader is judging it on, so it is set in ink rather
   than in the mute the rest of the mono furniture takes. */
.pen__freshness {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
}

/* Recently bounced is an audit trail rather than a list to act on, so it
   steps down the way Briefly steps down from a lead story — the type scale
   hangs off the section, and no partial asks which one it is in. */
.pen__section--bounced .pen__subject {
  font-size: 16px;
  font-weight: 500;
  color: var(--body);
}

/* The Sources section. One shape as the pen's sections above it — the type
   scale hangs off the section name, so no partial asks which one it is in —
   with a form at the top, because this is the only section of this page the
   reader writes to rather than only reads. */
.sources__form {
  padding-top: 24px;
}

.sources__label {
  display: block;
  margin-bottom: 10px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--mute);
}

/* Stacked below 720px for the reason the waitlist's are: "Follow" in mono
   beside an input is wider than a 390px screen leaves room for, and squeezing
   both onto one line pushes the button off the page. */
.sources__controls {
  display: grid;
  grid-template-columns: 1fr;
}

/* width, because a refused form comes back wrapped: Rails' field_error_proc
   puts a div round the input, that div becomes the grid item, and the input
   falls back to its intrinsic 219px — clipping the address the reader typed
   at exactly the moment the page is explaining why it was refused. */
.sources__input {
  width: 100%;
  border: 0;
  border-bottom: 2px solid var(--ink);
  border-radius: 0;
  background: transparent;
  padding: 12px 0;
  font-family: var(--sans);
  font-size: 17px;
  color: var(--ink);
}

.sources__input::placeholder {
  color: var(--read);
}

/* Something has to change on focus, and the underline is already there to
   change. focus-visible so a click does not draw it and a Tab does. */
.sources__input:focus {
  outline: 0;
}

.sources__input:focus-visible {
  border-bottom-color: var(--blue);
}

.sources__submit {
  border: 0;
  border-radius: 0;
  background: var(--ink);
  color: var(--paper);
  padding: 14px 22px;
  margin-top: 16px;
  justify-self: start;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
}

.sources__submit:hover {
  background: var(--blue);
}

/* Set in ink and in sentence case: this is the app explaining itself to
   somebody who has just been told no, and it is the one moment there is to
   say why. */
.sources__error {
  margin: 16px 0 0;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
}

.sources__note {
  margin: 14px 0 0;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  line-height: 1.7;
  text-transform: uppercase;
  color: var(--mute);
}

/* Not a link, so the grid sits on the item itself where the pen's sits on
   the line inside it. */
.pen__item--source {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  row-gap: 4px;
  column-gap: 16px;
  padding: 16px 0;
}

.sources__name {
  grid-column: 1;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.02em;
  color: var(--ink);
  overflow-wrap: anywhere;
}

/* Lower case, and the one place in this app mono is. The rule is that mono is
   always uppercase; an uppercased URL is a wrong URL to read or to copy, and
   this is the address the reader typed and may need to check. The reason is
   here because .claude/rules asks for one when a rule is broken.

   --mute rather than --read: #9a9a9a on paper is 2.81:1, under even the 3:1
   floor for non-text, and this is 10px. --mute is 5.41:1 and is what the
   count and the state beside it take. */
.sources__feed {
  grid-column: 1;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--mute);
  overflow-wrap: anywhere;
}

.sources__count,
.sources__state {
  grid-column: 1;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--mute);
}

/* The one thing on this page the reader has to act on, so it is the one thing
   set in ink rather than in the mute the rest of the mono furniture takes —
   the same move the pen makes for how long a confirmation has waited. */
.sources__state--failing {
  color: var(--ink);
}

/* button_to generates a <button> inside a <form> under Rails 8 defaults, so
   the grid placement goes on the form — which is the grid item — and the
   appearance on the button. Styling ` input` matched only the hidden _method
   field, and left the control at the browser's own Arial, outset border and
   rounded corners: a third typeface, a rule weight the system does not have,
   and a radius, in one control. */
.sources__remove-form {
  grid-column: 2;
  grid-row: 1 / -1;
  align-self: center;
  margin: 0;
}

/* Borderless mute text, which is the app's second button treatment, after
   .topbar__action. A bordered one would be a third the system does not have
   — and --rule on paper is 1.28:1, well under the 3:1 a control edge needs
   to be seen at all. */
.sources__remove {
  border: 0;
  border-radius: 0;
  background: none;
  color: var(--mute);
  padding: 0;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
}

.sources__remove:hover {
  color: var(--ink);
}

.pen__empty {
  margin: 0;
  padding: 24px 0 4px;
  font-size: 17px;
  line-height: 1.65;
  color: var(--body);
  text-wrap: pretty;
}

@media (min-width: 720px) {
  .pen {
    padding-bottom: 96px;
  }

  .pen__section {
    padding-top: 56px;
  }

  .pen__heading {
    padding-bottom: 10px;
    font-size: 11px;
  }

  /* Sender and freshness take columns of their own and the subject holds the
     middle. The line grows a hover tint and the padding to hold it, as the
     archive's row does and for the same reason: below this width there is no
     pointer to answer. */
  .pen__line {
    grid-template-columns: 150px 1fr auto;
    align-items: baseline;
    column-gap: 24px;
    row-gap: 0;
    padding: 18px 14px;
    margin: 0 -14px;
  }

  .pen__line--open:hover {
    background: var(--hover);
  }

  .pen__sender,
  .pen__freshness {
    font-size: 11px;
  }

  .pen__subject {
    font-size: 19px;
  }

  .pen__empty {
    padding: 32px 0 8px;
  }

  /* The Blogs section takes the same step up as the sections above it. Left
     at its mobile sizes the whole thing read one notch smaller than identical
     furniture six lines up the page — spacing is untokenised on purpose, the
     type scale is not. */
  .sources__label,
  .sources__submit,
  .sources__count,
  .sources__feed,
  .sources__state,
  .sources__remove {
    font-size: 11px;
  }

  .sources__name {
    font-size: 19px;
  }

  .pen__item--source {
    padding: 18px 0;
  }

  /* Input and button on one line, as the waitlist's are above this width and
     for the same reason: below it, "Follow" set in mono beside a field is
     wider than a 390px screen leaves room for. */
  .sources__controls {
    grid-template-columns: 1fr auto;
    align-items: end;
  }

  .sources__submit {
    margin-top: 0;
    margin-left: 20px;
  }
}

/* Settings ------------------------------------------------------------------ */

/* One section, one fact: the address a subscription gets pointed at. Same
   shape as the pen's sections — a mono heading on the 2px rule — because it
   is the same kind of page, a reference rather than something to act on. */
.settings {
  padding: 0 var(--gutter) 48px;
}

.settings__section {
  max-width: var(--measure);
  margin: 0 auto;
  padding-top: 32px;
}

.settings__heading {
  margin: 0;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--ink);
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.settings__address {
  margin: 0;
  padding: 24px 0 4px;
  font-family: var(--mono);
  font-size: 17px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ink);
}

.settings__note {
  margin: 0;
  padding: 8px 0 4px;
  font-size: 15px;
  line-height: 1.65;
  color: var(--body);
  text-wrap: pretty;
}

@media (min-width: 720px) {
  .settings {
    padding: 0 var(--gutter) 72px;
  }

  .settings__section {
    padding-top: 56px;
  }

  .settings__heading {
    padding-bottom: 10px;
    font-size: 11px;
  }

  .settings__address {
    font-size: 19px;
  }
}

/* Feed -------------------------------------------------------------------- */

.feed {
  padding: 0 var(--gutter) 48px;
}

.feed__group {
  padding-top: 24px;
}

.feed__group-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  border-bottom: 2px solid var(--ink);
  padding-bottom: 8px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.feed__group-label {
  margin: 0;
  font-family: inherit;
  font-size: inherit;
  font-weight: 500;
  letter-spacing: inherit;
}

.feed__group-sublabel {
  color: var(--mute);
}

.feed__end {
  padding-top: 28px;
  font-family: var(--mono);
  font-size: 10px;
  line-height: 1.9;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--mute);
}

.feed__end-line {
  margin: 0;
}

.feed__empty {
  padding: 48px 0;
  font-size: 17px;
  line-height: 1.65;
  color: var(--body);
  text-wrap: pretty;
}

@media (min-width: 720px) {
  .feed {
    padding: 0 var(--gutter) 72px;
  }

  .feed__group {
    padding-top: 48px;
  }

  .feed__group-header {
    padding-bottom: 10px;
    font-size: 11px;
  }

  .feed__end {
    font-size: 11px;
  }

  .feed__empty {
    padding: 72px 0;
    max-width: var(--measure);
  }
}

/* Lead item --------------------------------------------------------------- */

/* The newest item in the feed, when it has an image. Grid areas rather than
   nested markup so the number, sender and time collapse onto one mono line
   below 720px and split into their own columns above it. */
.lead {
  display: grid;
  grid-template-columns: auto auto 1fr;
  column-gap: 0;
  grid-template-areas:
    "image   image   image"
    "number  sender  time"
    "subject subject subject"
    "snippet snippet snippet";
  padding: 20px 0 24px;
  border-bottom: 1px solid var(--rule);
  text-decoration: none;
  color: inherit;
}

.lead__image {
  grid-area: image;
  display: block;
  width: 100%;
  height: 200px;
  object-fit: cover;
  margin-bottom: 14px;
  background: var(--hover);
}

.lead__number,
.lead__sender,
.lead__timestamp {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--mute);
}

.lead__number {
  grid-area: number;
  color: var(--blue);
}

/* The mono line reads "01 / RUBY WEEKLY / 06:12" on mobile. The separators
   belong to the layout, not to the copy, so they are drawn rather than
   translated — and they go away when the three split into columns. */
.lead__number::after,
.lead__sender::after {
  content: "\00a0/\00a0";
}

.lead__sender {
  grid-area: sender;
}

/* The same marker a standard row carries, drawn the same way: the separator
   belongs to the layout rather than to the copy. Only posts wear it — they
   are the rarer thing, so marking them keeps the line quieter than marking
   twenty newsletters a day would. */
.lead__kind {
  color: var(--blue);
}

.lead__kind::before {
  content: "\00a0/\00a0";
  color: var(--mute);
}

.lead__subject {
  grid-area: subject;
  margin-top: 8px;
  font-size: 24px;
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.03em;
  text-wrap: pretty;
}

.lead__snippet {
  display: none;
}

.lead__timestamp {
  grid-area: time;
  justify-self: start;
}

@media (min-width: 720px) {
  .lead {
    grid-template-columns: 44px 1fr 96px;
    column-gap: 24px;
    grid-template-areas:
      "image  image   image"
      "number sender  time"
      "number subject time"
      "number snippet time";
    padding: 32px 0 36px;
  }

  .lead__image {
    height: 360px;
    margin-bottom: 28px;
  }

  .lead__number,
  .lead__timestamp {
    font-size: 12px;
    letter-spacing: 0;
  }

  .lead__sender {
    font-size: 11px;
  }

  .lead__number::after,
  .lead__sender::after {
    content: none;
  }

  .lead__subject {
    margin-top: 12px;
    max-width: 900px;
    font-size: 40px;
    line-height: 1.08;
    letter-spacing: -0.035em;
  }

  .lead__snippet {
    grid-area: snippet;
    display: block;
    margin-top: 14px;
    max-width: 640px;
    font-size: 16px;
    line-height: 1.6;
    color: var(--mute);
    text-wrap: pretty;
  }

  .lead__timestamp {
    justify-self: end;
  }
}

/* Feed row ---------------------------------------------------------------- */

.row {
  display: grid;
  grid-template-columns: auto auto 1fr 92px;
  column-gap: 0;
  grid-template-areas:
    "number  sender  time    thumb"
    "subject subject subject thumb"
    "snippet snippet snippet thumb";
  align-items: start;
  padding: 20px 0;
  border-bottom: 1px solid var(--rule);
  text-decoration: none;
  color: inherit;
}

.row__number,
.row__sender,
.row__timestamp {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--mute);
}

/* The index number, in the accent colour: it is what makes the archive read
   as a numbered list rather than a stack of cards. */
.row__number {
  grid-area: number;
  color: var(--blue);
}

.row__number::after {
  content: "\00a0/\00a0";
}

.row__sender {
  grid-area: sender;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The one field that says a row is a blog post rather than a newsletter. The
   mono line already reads as slash-separated fields, so the separator is
   drawn here rather than written into the locale — the same way the story
   sources list draws its own. */
.row__kind {
  color: var(--blue);
}

.row__kind::before {
  content: "\00a0/\00a0";
  color: var(--mute);
}

.row__subject {
  grid-area: subject;
  margin-top: 6px;
  font-size: 18px;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-wrap: pretty;
}

.row__snippet {
  display: none;
}

.row__timestamp {
  grid-area: time;
  justify-self: end;
}

.row__thumbnail {
  grid-area: thumb;
  display: block;
  margin-left: 16px;
  width: 92px;
  height: 68px;
  object-fit: cover;
  background: var(--hover);
}

/* The dashed box keeps the right edge aligned. Without it every row with no
   image pulls its text wider than the rows around it. */
.row__thumbnail--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px dashed var(--rule);
  padding: 0 8px;
  background: none;
}

.row__fallback {
  display: none;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: center;
  color: var(--fallback);
}

.row__fallback--compact {
  display: block;
}

@media (min-width: 720px) {
  .row {
    grid-template-columns: 44px 1fr 200px 96px;
    column-gap: 24px;
    grid-template-areas:
      "number sender  thumb time"
      "number subject thumb time"
      "number snippet thumb time";
    padding: 24px 14px;
    margin: 0 -14px;
  }

  .row:hover {
    background: var(--hover);
  }

  .row__number,
  .row__timestamp {
    padding-top: 4px;
    font-size: 12px;
    letter-spacing: 0;
  }

  .row__number::after {
    content: none;
  }

  .row__sender {
    font-size: 11px;
    letter-spacing: 0.08em;
  }

  .row__subject {
    margin-top: 7px;
    font-size: 23px;
  }

  .row__snippet {
    grid-area: snippet;
    display: block;
    margin-top: 8px;
    max-width: 520px;
    font-size: 14px;
    line-height: 1.6;
    color: var(--mute);
    text-wrap: pretty;
  }

  .row__thumbnail {
    margin-left: 0;
    width: 200px;
    height: 132px;
  }

  .row__thumbnail--empty {
    padding: 0 12px;
  }

  .row__fallback {
    display: block;
    font-size: 10px;
    letter-spacing: 0.08em;
  }

  .row__fallback--compact {
    display: none;
  }
}

/* Original top bar -------------------------------------------------------- */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 22px var(--gutter);
  border-bottom: 2px solid var(--ink);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.topbar__back {
  color: var(--blue);
  text-decoration: none;
}

/* The arrow points the way back; it is direction, not copy, so it is drawn
   here rather than translated. */
.topbar__back::before {
  content: "←\00a0\00a0";
}

.topbar__actions {
  display: flex;
  align-items: center;
  gap: 20px;
}

.topbar__action {
  color: var(--mute);
  text-decoration: none;
  font-family: inherit;
  font-size: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

.topbar__action:hover {
  color: var(--ink);
}

.topbar__form {
  display: inline;
}

@media (min-width: 720px) {
  .topbar {
    font-size: 11px;
  }

  .topbar__actions {
    gap: 26px;
  }
}

/* Pen top bar ------------------------------------------------------------- */

/* What a held confirmation wears in place of the archive's bar: the same
   furniture at the same weights, with two differences that are both about the
   pen rather than about the look.

   It wraps rather than hiding an action below 720px. A phone is where mail
   gets read, and a misfire the reader cannot release from one stays in the
   pen until they are at a desk — which a confirm link may not outlast.

   Done is set in ink against the mute the other action keeps. It is the
   ending nearly every hold has and the one the reader came here to press. */
.topbar--pen {
  flex-wrap: wrap;
  row-gap: 12px;
}

.topbar__action--done {
  color: var(--ink);
}

/* View original ----------------------------------------------------------- */

.original {
  padding: 40px var(--gutter) 72px;
}

.original__caption {
  max-width: var(--measure);
  margin: 0 auto 24px;
  font-size: 13px;
  color: var(--mute);
}

.original__frame {
  display: block;
  width: 100%;
  max-width: var(--measure);
  height: 85vh;
  margin: 0 auto;
  border: 1px solid var(--rule);
  background: #ffffff;
}

/* Sign in ----------------------------------------------------------------- */

/* The gate onto the app, on the same system as everything behind it: mono
   labels, no radius, a 2px rule under each field and a solid black button. */
.signin {
  max-width: 380px;
  margin: 96px auto;
  padding: 0 var(--gutter);
}

.signin__lockup {
  margin-bottom: 56px;
}

.signin__title {
  margin: 0 0 32px;
  font-size: 40px;
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.035em;
}

.signin__field {
  display: block;
  margin-bottom: 28px;
}

.signin__label {
  display: block;
  margin-bottom: 14px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--mute);
}

.signin__input {
  width: 100%;
  padding: 14px 0;
  border: 0;
  border-bottom: 2px solid var(--ink);
  border-radius: 0;
  background: transparent;
  font-family: var(--sans);
  font-size: 19px;
  color: var(--ink);
}

.signin__input:focus {
  outline: 0;
}

.signin__submit {
  border: 0;
  border-radius: 0;
  background: var(--ink);
  padding: 14px 32px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--paper);
  cursor: pointer;
}

.signin__submit:hover {
  background: var(--blue);
}

.signin__alert {
  margin-bottom: 32px;
  border-top: 2px solid var(--ink);
  padding-top: 16px;
  font-size: 16px;
  line-height: 1.6;
  color: var(--body);
}

.signin__forgot {
  margin-top: 44px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.signin__forgot a {
  text-decoration: none;
}

.signin__forgot a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Landing page ------------------------------------------------------------ */

/* The only textured surface in the system, and the only page a signed-out
   visitor can reach. */
.landing {
  min-height: 100vh;
  background-color: var(--landing-paper);
  background-image: radial-gradient(rgba(10, 10, 10, 0.13) 1px, transparent 1px);
  background-size: 28px 28px;
  background-position: -1px -1px;
}

.landing__frame {
  max-width: var(--frame);
  margin: 0 auto;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}

.landing__nav {
  border-bottom: 2px solid var(--ink);
}

.landing__nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-top: 22px;
  padding-bottom: 22px;
}

.landing__nav-link {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
}

.landing__nav-link::after {
  content: "\00a0→";
}

.landing__hero {
  padding-top: 64px;
}

.landing__eyebrow {
  margin: 0 0 24px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--blue);
}

.landing__title {
  margin: 0;
  max-width: 1000px;
  font-size: 48px;
  font-weight: 800;
  line-height: 0.98;
  letter-spacing: -0.04em;
}

.landing__standfirst {
  margin: 24px 0 0;
  max-width: var(--measure);
  font-size: 18px;
  line-height: 1.5;
  color: var(--body);
  text-wrap: pretty;
}

.landing__hero .waitlist,
.landing__hero .joined {
  margin-top: 40px;
}

.landing__shot {
  padding-top: 64px;
}

.landing__points {
  display: grid;
  grid-template-columns: 1fr;
  gap: 48px;
  padding-top: 72px;
}

.landing__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-top: 32px;
  padding-bottom: 48px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--mute);
}

.landing__footer-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--ink);
}

@media (min-width: 720px) {
  .landing__hero {
    padding-top: 96px;
  }

  .landing__nav-link,
  .landing__eyebrow {
    font-size: 11px;
  }

  .landing__title {
    font-size: 88px;
    letter-spacing: -0.045em;
  }

  .landing__standfirst {
    margin-top: 32px;
    font-size: 23px;
  }

  .landing__hero .waitlist,
  .landing__hero .joined {
    margin-top: 56px;
  }

  .landing__shot {
    padding-top: 96px;
  }

  .landing__points {
    grid-template-columns: 1fr 1fr;
    column-gap: 80px;
    padding-top: 120px;
  }

  .landing__footer {
    padding-bottom: 56px;
  }
}

/* Waitlist form ----------------------------------------------------------- */

.waitlist {
  max-width: 620px;
}

.waitlist__label {
  display: block;
  margin-bottom: 14px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--mute);
}

/* Stacked below 720px: "Join the waitlist" set in mono at 10px is wider than
   the room a 390px screen leaves beside an input, and squeezing both onto one
   line pushed the button off the page. */
.waitlist__controls {
  display: grid;
  grid-template-columns: 1fr;
}

.waitlist__input {
  border: 0;
  border-bottom: 2px solid var(--ink);
  border-radius: 0;
  background: transparent;
  padding: 14px 0;
  font-family: var(--sans);
  font-size: 19px;
  color: var(--ink);
}

.waitlist__input::placeholder {
  color: var(--read);
}

.waitlist__input:focus {
  outline: 0;
}

.waitlist__submit {
  border: 0;
  border-radius: 0;
  background: var(--ink);
  color: var(--paper);
  padding: 16px 24px;
  margin-top: 20px;
  justify-self: start;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
}

.waitlist__submit:hover {
  background: var(--blue);
}

/* Off-screen rather than display:none or type="hidden", both of which a bot
   filling the form knows to skip. aria-hidden and tabindex keep it away from
   anyone using the page properly. */
.waitlist__honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.waitlist__error {
  margin: 16px 0 0;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
}

.waitlist__note {
  margin: 16px 0 0;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--mute);
}

.waitlist--inverted .waitlist__label {
  color: var(--read);
}

.waitlist--inverted .waitlist__input {
  border-bottom-color: var(--paper);
  color: var(--paper);
}

.waitlist--inverted .waitlist__submit {
  background: var(--paper);
  color: var(--ink);
}

.waitlist--inverted .waitlist__submit:hover {
  background: var(--blue);
  color: var(--paper);
}

.waitlist--inverted .waitlist__error {
  color: var(--paper);
}

/* The handoff keeps this note at --mute in the dark band, which is 2.5:1 on
   ink and fails AA. --read is the grey the band already uses for its own
   paragraph, and clears 5:1. */
.waitlist--inverted .waitlist__note {
  color: var(--read);
}

@media (min-width: 720px) {
  .waitlist__controls {
    grid-template-columns: 1fr auto;
    align-items: stretch;
  }

  .waitlist__submit {
    padding: 0 32px;
    margin-top: 0;
    margin-left: 20px;
    font-size: 11px;
  }

  .waitlist__note {
    font-size: 11px;
  }
}

/* Waitlist success -------------------------------------------------------- */

.joined {
  max-width: 620px;
  border-top: 2px solid var(--ink);
  padding-top: 24px;
}

.joined__label {
  margin: 0 0 14px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--blue);
}

.joined__email {
  margin: 0;
  font-size: 23px;
  font-weight: 600;
  letter-spacing: -0.02em;
  overflow-wrap: anywhere;
}

.joined__note {
  margin: 12px 0 0;
  font-size: 16px;
  line-height: 1.6;
  color: var(--mute);
  text-wrap: pretty;
}

.joined--inverted {
  border-top-color: var(--paper);
}

.joined--inverted .joined__label {
  color: var(--paper);
}

.joined--inverted .joined__note {
  color: var(--read);
}

/* Two points -------------------------------------------------------------- */

.point {
  border-top: 2px solid var(--ink);
  padding-top: 20px;
}

.point__kicker {
  margin: 0 0 16px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--blue);
}

.point__title {
  margin: 0;
  font-size: 28px;
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.03em;
}

.point__body {
  margin: 16px 0 0;
  max-width: 460px;
  font-size: 17px;
  line-height: 1.65;
  color: var(--body);
  text-wrap: pretty;
}

@media (min-width: 720px) {
  .point__title {
    font-size: 32px;
  }
}

/* Closing band ------------------------------------------------------------ */

.closing {
  background: var(--ink);
  color: var(--paper);
  margin-top: 72px;
}

.closing__inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: 48px;
  align-items: start;
  padding-top: 64px;
  padding-bottom: 64px;
}

.closing__title {
  margin: 0;
  font-size: 36px;
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -0.04em;
}

.closing__body {
  margin: 20px 0 0;
  max-width: 420px;
  font-size: 17px;
  line-height: 1.6;
  color: var(--read);
  text-wrap: pretty;
}

@media (min-width: 720px) {
  .closing {
    margin-top: 120px;
  }

  .closing__inner {
    grid-template-columns: 1fr 620px;
    column-gap: 80px;
    padding-top: 96px;
    padding-bottom: 96px;
  }

  .closing__title {
    font-size: 52px;
  }
}

/* Product shot ------------------------------------------------------------ */

/* Fixed sample content, at the feed's row spec and reduced scale. Not the
   reader's own feed: this page is unauthenticated. */
.shot {
  border: 1px solid var(--ink);
  background: var(--paper);
}

.shot__caption {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 20px;
  border-bottom: 2px solid var(--ink);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.shot__subcaption {
  color: var(--mute);
}

.shot__body {
  padding: 0 20px 24px;
}

.shot__group {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  border-bottom: 2px solid var(--ink);
  padding: 24px 0 8px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.shot__date {
  color: var(--mute);
}

.shot__row {
  display: grid;
  grid-template-columns: 28px 1fr 60px;
  column-gap: 12px;
  align-items: baseline;
  padding: 14px 0;
  border-bottom: 1px solid var(--rule);
}

.shot__row--read {
  opacity: 0.66;
}

.shot__number,
.shot__time {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--blue);
}

.shot__row--read .shot__number {
  color: var(--read);
}

.shot__time {
  color: var(--mute);
  text-align: right;
}

.shot__text {
  display: block;
  min-width: 0;
}

.shot__sender {
  display: block;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--mute);
}

.shot__subject {
  display: block;
  margin-top: 6px;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.02em;
  text-wrap: pretty;
}

@media (min-width: 720px) {
  .shot__caption,
  .shot__body {
    padding-left: 28px;
    padding-right: 28px;
  }

  .shot__group {
    padding-top: 32px;
  }

  .shot__body {
    padding-bottom: 36px;
  }

  .shot__row {
    grid-template-columns: 36px 1fr 80px;
    column-gap: 20px;
    padding: 18px 0;
  }

  .shot__subject {
    font-size: 20px;
  }
}

