/*
 * The whole stylesheet, as one file of static classes.
 *
 * The design studies carry an inline style on every node; repeating those in
 * the server-rendered HTML would multiply the size of a 300-message page and
 * the CPU spent producing it. Everything that varies per reader is a class, so
 * the markup stays short and the CSS caches once.
 *
 * A different theme — dark, say, which this does not ship — is a redefinition
 * of the variables below and nothing else.
 */

:root {
  --paper: #fdfcfa;
  --paper-sticky: rgba(253, 252, 250, 0.96);
  --surface: #f7f5f1;
  --rail: #faf8f5;
  --code: #f4f2ed;

  --ink: #1c1b19;
  --body: #26241f;
  --sub: #5d574e;
  --meta: #8a857c;
  --faint: #a8a29a;
  --fainter: #b6b0a6;
  --faintest: #c4beb4;
  --code-ink: #3c3830;

  --link: #3f6392;
  --link-hover: #284b78;
  --mention-bg: rgba(63, 99, 146, 0.13);
  --highlight: #f3e2a8;

  --rule: rgba(0, 0, 0, 0.08);
  --rule-strong: rgba(0, 0, 0, 0.12);
  --rule-msg: rgba(0, 0, 0, 0.1);
  --tint: rgba(0, 0, 0, 0.055);

  --bar: #ded9d0;
  --bar-here: var(--link);

  --sans: "IBM Plex Sans JP", system-ui, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, monospace;

  --gutter: 74px;
  --rail-width: 220px;

  /* Author colours. Dark enough to hold contrast on the paper background. */
  --author-0: #3f6392;
  --author-1: #8a5a3c;
  --author-2: #4a7a52;
  --author-3: #7a4a6e;
  --author-4: #2f6f78;
  --author-5: #8a6a2f;
  --author-6: #55507a;
  --author-7: #8a4a4a;
}

html,
body {
  margin: 0;
  height: 100%;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
}

a {
  color: var(--link);
  text-decoration: none;
}

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

/* ---------------------------------------------------------------- chrome -- */

.shell {
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.top {
  flex: none;
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: 12px 20px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.09);
  background: var(--surface);
}

.crumbs {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}

/*
 * Ancestors give up width first; the last step never does. Clipping the name of
 * the page the reader is on to fit the path they took to it has it backwards.
 */
.crumb {
  min-width: 0;
  font: 400 14px / 1.2 var(--sans);
  color: var(--meta);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

a.crumb:hover {
  color: var(--link-hover);
}

/* The root is short and fixed; clipping it buys nothing. */
.crumbs > .crumb:first-child {
  flex: none;
}

.crumb--here {
  flex: none;
  font-weight: 600;
  color: var(--ink);
}

.crumb-sep {
  flex: none;
  color: var(--faintest);
}

.channel-meta {
  font: 400 11px / 1 var(--mono);
  color: var(--faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.top-side {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
  align-self: center;
  margin-left: auto;
}

.auth {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font: 400 11px / 1 var(--mono);
  white-space: nowrap;
}

.auth-name {
  color: var(--meta);
  max-width: 14ch;
  overflow: hidden;
  text-overflow: ellipsis;
}

.auth-form {
  display: flex;
  margin: 0;
}

/* Also worn by the sign-out submit button, which is a button only so that the
   browser sends a POST; it reads as the link next to it. */
.auth-link {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--link);
  cursor: pointer;
}

.auth-link:hover {
  color: var(--link-hover);
}

.warn {
  margin: 0;
  padding: 8px 20px;
  background: var(--highlight);
  color: var(--ink);
  font: 400 11.5px / 1.5 var(--mono);
}

.frame {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--rail-width);
}

/* ------------------------------------------------------------------ log -- */

.log {
  min-height: 0;
  overflow: auto;
  border-right: 1px solid var(--rule);
  padding-bottom: 28px;
}

.stream {
  display: grid;
  grid-template-columns: var(--gutter) minmax(0, 1fr);
  max-width: 1080px;
}

.daynode {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  padding: 20px 24px 10px 0;
  position: sticky;
  top: 0;
  background: var(--paper-sticky);
  z-index: 1;
}

.daynode-date {
  width: var(--gutter);
  text-align: right;
  padding-right: 12px;
  font: 500 11px / 1 var(--mono);
}

.daynode-dot {
  width: 9px;
  height: 9px;
  border-radius: 5px;
  background: var(--ink);
  margin-left: -4.5px;
  flex: none;
}

.daynode-rule {
  flex: 1;
  height: 1px;
  background: var(--rule-strong);
  margin-left: 10px;
}

.daynode-meta {
  font: 400 10.5px / 1 var(--mono);
  color: var(--fainter);
  padding-left: 10px;
  white-space: nowrap;
}

.at {
  grid-column: 1;
  text-align: right;
  padding-right: 12px;
  font: 400 11px / 1.7 var(--mono);
  color: var(--fainter);
}

.msg {
  grid-column: 2;
  border-left: 1px solid var(--rule-msg);
  padding-right: 24px;
  padding-left: 20px;
  font: 400 13.5px / 1.65 var(--sans);
  color: var(--body);
  text-wrap: pretty;
  min-width: 0;
}

/* Spacing carries the grouping: first of a day, same speaker, new speaker. */
.at--lead,
.msg--lead {
  padding-top: 6px;
}

.at--cont,
.msg--cont {
  padding-top: 2px;
}

.at--start,
.msg--start {
  padding-top: 10px;
}

.line {
  min-width: 0;
}

.who {
  font: 600 12.5px / 1 var(--mono);
  margin-right: 8px;
}

.au0 {
  color: var(--author-0);
}
.au1 {
  color: var(--author-1);
}
.au2 {
  color: var(--author-2);
}
.au3 {
  color: var(--author-3);
}
.au4 {
  color: var(--author-4);
}
.au5 {
  color: var(--author-5);
}
.au6 {
  color: var(--author-6);
}
.au7 {
  color: var(--author-7);
}

/*
 * Holds the width the name took on a continuation, so a run of messages from
 * one person keeps a single left edge. Hidden rather than absent because the
 * width has to match the name exactly, and names are not a fixed size.
 */
.who--ghost {
  visibility: hidden;
  user-select: none;
}

.bot {
  margin-left: 5px;
  padding: 1px 4px;
  border: 1px solid var(--rule-strong);
  border-radius: 3px;
  font: 500 9px / 1.3 var(--mono);
  color: var(--meta);
  vertical-align: 1px;
}

.quote {
  font: 400 11.5px / 1.6 var(--sans);
  color: var(--faint);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.quote-name {
  color: var(--meta);
}

.edited,
.meta-note {
  margin-left: 6px;
  font: 400 10.5px / 1 var(--mono);
  color: var(--fainter);
  white-space: nowrap;
}

.tick {
  font: 400 12.5px / 1.5 var(--mono);
  background: var(--tint);
  padding: 1px 5px;
  border-radius: 3px;
}

.mention {
  background: var(--mention-bg);
  color: var(--link);
  padding: 1px 4px;
  border-radius: 3px;
}

.code {
  margin: 6px 0 0;
  padding: 10px 12px;
  background: var(--code);
  border: 1px solid rgba(0, 0, 0, 0.07);
  border-radius: 4px;
  font: 400 12px / 1.65 var(--mono);
  color: var(--code-ink);
  overflow-x: auto;
}

.thread {
  margin-top: 8px;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 7px 11px;
  border: 1px dashed rgba(0, 0, 0, 0.18);
  border-radius: 4px;
  color: var(--ink);
}

.thread:hover {
  border-color: var(--link);
  color: var(--ink);
}

.thread-tag {
  font: 500 10.5px / 1 var(--mono);
  color: var(--meta);
}

.thread-name {
  font: 600 12.5px / 1 var(--sans);
}

.thread-count {
  font: 400 11px / 1 var(--mono);
  color: var(--faint);
}

.empty {
  grid-column: 2;
  padding: 24px;
  font: 400 12px / 1 var(--mono);
  color: var(--meta);
}

.pager {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 22px 24px 0 var(--gutter);
  font: 400 11.5px / 1 var(--mono);
}

.pager--top {
  padding-top: 14px;
  padding-bottom: 2px;
  justify-content: flex-start;
}

.pager-step {
  color: var(--link);
}

.pager-step:hover {
  color: var(--link-hover);
}

.pager-at {
  color: var(--faint);
}

/* ----------------------------------------------------------------- rail -- */

.rail {
  min-height: 0;
  overflow: auto;
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 20px;
  background: var(--rail);
}

.rail-block {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.rail-block--last {
  padding-top: 12px;
  border-top: 1px solid var(--rule);
}

.rail-head {
  margin: 0;
  font: 500 10.5px / 1 var(--mono);
  letter-spacing: 0.1em;
  color: var(--faint);
}

.rail-list {
  display: flex;
  flex-direction: column;
  gap: 7px;
  font: 400 12px / 1 var(--sans);
  color: var(--sub);
}

.rail-list--mono {
  gap: 6px;
  font-family: var(--mono);
}

.rail-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  color: var(--sub);
}

a.rail-row:hover {
  color: var(--link-hover);
}

.rail-row--here > span:first-child {
  color: var(--ink);
  font-weight: 500;
}

.rail-row .who {
  font: 600 12px / 1 var(--sans);
  margin-right: 0;
}

.rail-n {
  color: var(--fainter);
  font-family: var(--mono);
}

.rail-more {
  padding-top: 2px;
  font-size: 11px;
  color: var(--link);
}

/*
 * A fixed number of slots, matching ACTIVITY_DAYS in views/rail.tsx. Sizing the
 * bars by how many there are would make a channel with three archived days draw
 * three bars the width of the rail, which reads as a different chart rather than
 * a shorter one.
 */
.bars {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  align-items: end;
  gap: 3px;
  height: 52px;
}

.bar {
  background: var(--bar);
  min-height: 3px;
}

.bar--here {
  background: var(--bar-here);
}

/*
 * Present to a screen reader, absent to everyone else. The activity bars say
 * what they mean through their height, which reads as nothing at all.
 */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  white-space: nowrap;
  clip-path: inset(50%);
}

.rail-note {
  margin: 0;
  font: 400 10px / 1.5 var(--mono);
  color: var(--fainter);
}

.rail-note--strong {
  font-size: 11.5px;
  line-height: 1.6;
  color: var(--sub);
}

.rail-open,
.rail-close {
  display: none;
  font: 400 11px / 1 var(--mono);
  color: var(--sub);
  background: none;
  border: 1px solid var(--rule-strong);
  border-radius: 4px;
  padding: 0 10px;
  min-height: 32px;
  cursor: pointer;
}

.scrim {
  display: none;
}

/* --------------------------------------------------------------- sheets -- */

.shell--plain {
  height: auto;
  min-height: 100vh;
}

.sheet {
  max-width: 760px;
  padding: 24px 20px 48px;
}

.cards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.card {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
}

.card-name {
  font: 600 13.5px / 1.4 var(--sans);
  color: var(--link);
}

.card:hover .card-name {
  color: var(--link-hover);
}

.card-meta {
  font: 400 11px / 1 var(--mono);
  color: var(--faint);
  margin-left: auto;
  white-space: nowrap;
}

/* ------------------------------------------------------------- sign-in -- */

.signin {
  max-width: 460px;
}

.signin-title {
  margin: 0 0 10px;
  font: 600 16px / 1.4 var(--sans);
}

.signin-body {
  margin: 0 0 22px;
  font: 400 13.5px / 1.7 var(--sans);
  color: var(--body);
}

.signin-cancelled {
  margin: 0 0 22px;
  padding: 8px 12px;
  background: var(--highlight);
  color: var(--ink);
  font: 400 11.5px / 1.6 var(--mono);
}

.signin-form {
  margin: 0;
}

.signin-go {
  display: inline-flex;
  align-items: center;
  padding: 10px 18px;
  border: 1px solid var(--rule-strong);
  border-radius: 4px;
  background: var(--surface);
  color: var(--link);
  font: 500 12.5px / 1 var(--mono);
  cursor: pointer;
}

.signin-go:hover {
  border-color: var(--link);
  color: var(--link-hover);
}

.signin-note {
  margin: 20px 0 0;
  font: 400 11px / 1.7 var(--mono);
  color: var(--meta);
}

.notice-title {
  margin: 0 0 8px;
  font: 600 16px / 1.4 var(--sans);
}

.notice-body {
  margin: 0;
  font: 400 13.5px / 1.65 var(--sans);
  color: var(--body);
}

.notice-detail {
  margin: 12px 0 0;
  font: 400 11.5px / 1.6 var(--mono);
  color: var(--meta);
}

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

@media (max-width: 760px) {
  :root {
    --gutter: 46px;
  }

  /* The trail and the counts stack, so the actions keep a full-height target. */
  .top {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    row-gap: 2px;
    padding: 9px 6px 9px 14px;
  }

  .crumbs {
    grid-column: 1;
    grid-row: 1;
  }

  .channel-meta {
    grid-column: 1;
    grid-row: 2;
    font-size: 10.5px;
  }

  .top-side {
    grid-column: 2;
    grid-row: 1 / span 2;
    margin-left: 0;
  }

  .frame {
    grid-template-columns: minmax(0, 1fr);
  }

  .log {
    border-right: none;
  }

  .stream {
    padding-bottom: 24px;
  }

  .daynode {
    padding-right: 14px;
  }

  .daynode-date {
    padding-right: 9px;
    font-size: 10.5px;
  }

  .at {
    padding-right: 9px;
    font-size: 10.5px;
    line-height: 1.8;
  }

  .msg {
    padding-left: 14px;
    padding-right: 14px;
    line-height: 1.7;
  }

  .thread {
    display: flex;
    min-height: 44px;
    box-sizing: border-box;
  }

  .thread-count {
    margin-left: auto;
  }

  .rail-open {
    display: inline-flex;
    align-items: center;
  }

  .rail-close {
    display: inline-flex;
    align-items: center;
    align-self: flex-end;
  }

  /* The rail becomes a drawer rather than disappearing: the jump-to list is
     how a phone reader moves through years of log. */
  .rail {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    /* Border-box, or the padding is added to the cap and the drawer covers the
       page it is supposed to be drawn over. */
    box-sizing: border-box;
    width: min(300px, 86vw);
    z-index: 3;
    transform: translateX(100%);
    transition: transform 0.16s ease-out;
    box-shadow: -8px 0 24px rgba(0, 0, 0, 0.08);
  }

  .drawer-open .rail {
    transform: none;
  }

  .drawer-open .scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 2;
    background: rgba(0, 0, 0, 0.18);
  }
}

@media (prefers-reduced-motion: reduce) {
  .rail {
    transition: none;
  }
}
