/* The pages outside the builder: library, keys, organization, pricing.
   Builds on app.css, so the tokens, the buttons and the type scale are shared.

   Everything here sits on the furō system: spacing is a multiple of 4, type is
   30/24/20/16/14/12, weights are 400 and 600, corners are square, and a border
   is 1px #DEDEDE that deepens to #707070 when you can interact with it.

   app.css turns body and main into a full-height flex column, because the
   builder is a workbench that fills the screen. An ordinary page scrolls
   instead, so that has to go back to normal here. Without these two rules
   everything ends up side by side. */

body.page {
  display: flex;
  min-height: 100%;
}

/* --------------------------------------------------------------- content -- */

.narrow {
  max-width: 460px;
  margin: var(--s16) auto;
}

/* The stage head carries the page title, so an h1 inside the body is a second
   heading on the same screen: signing in, an invitation, an error. Those are
   the pages without a rail, and there the display size is right. */
h1 {
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  font-weight: 400;
  letter-spacing: 0;
  margin: 0 0 var(--s3);
  text-wrap: balance;
}

.stagehead h1 {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: 600;
  margin: 0;
}

.lede {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--muted);
  max-width: var(--prose);
  margin: 0 0 var(--s6);
}

.pagehead {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s5);
  flex-wrap: wrap;
  margin-bottom: var(--s6);
}

.crumb {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--muted);
  margin: 0 0 var(--s3);
}

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

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

/* --- cards --- */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s6);
  margin-bottom: var(--s6);
}

.cardhead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  margin-bottom: var(--s4);
}

.cardhead h2 {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: 600;
  margin: 0;
}

.empty {
  color: var(--muted);
  margin: 0;
}

.emptystate {
  text-align: center;
  padding: var(--s16) var(--s6);
}

.emptystate .lede {
  margin: 0 auto var(--s6);
}

.emptystate h2 {
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  font-weight: 600;
  margin: 0 0 var(--s2);
}

/* ------------------------------------------------------------------ forms -- */

.form {
  display: flex;
  flex-direction: column;
  gap: var(--s4);
  margin: var(--s6) 0;
}

.form label,
.rowform label {
  display: block;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 600;
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="search"],
input[type="number"],
input[type="date"],
select {
  font: inherit;
  font-size: var(--fs-body);
  padding: var(--s3);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
  width: 100%;
  margin-top: var(--s2);
  transition: border-color var(--fast);
}

input:hover,
select:hover {
  border-color: var(--line-strong);
}

input:focus,
select:focus,
button:focus-visible,
a:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-color: var(--accent);
}

.rowform {
  display: flex;
  gap: var(--s2);
  align-items: center;
  flex-wrap: wrap;
}

.rowform input,
.rowform select {
  margin-top: 0;
  width: auto;
  flex: 1 1 260px;
}

.rowform label {
  font-weight: 400;
}

.inlineform {
  display: inline-block;
}

.searchbar {
  display: flex;
  gap: var(--s2);
  align-items: center;
  margin-bottom: var(--s6);
  flex-wrap: wrap;
}

.searchbar input {
  margin-top: 0;
  width: auto;
  flex: 0 1 380px;
}

/* ------------------------------------------------------ lists and tables -- */

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-small);
  line-height: var(--lh-small);
}

/* Mono and muted, in sentence case. Uppercase on a label is the one typographic
   thing the brand rules out by name. */
.table th {
  text-align: left;
  font-family: var(--mono);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: 500;
  color: var(--muted);
  border-bottom: 1px solid var(--line);
  padding: var(--s2) var(--s3) var(--s2) 0;
  white-space: nowrap;
}

.table td {
  padding: var(--s3) var(--s3) var(--s3) 0;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}

.table th:last-child,
.table td:last-child {
  padding-right: 0;
}

.table tr.off td {
  color: var(--muted);
}

.table .right {
  text-align: right;
  white-space: nowrap;
}

.table tr.severe td {
  background: var(--error-soft);
}

.table details summary {
  cursor: pointer;
  color: var(--muted);
}

/* Numbers line up. Any column of digits reads wrong without this. */
.table td code,
.table .num,
.meter + span {
  font-variant-numeric: tabular-nums;
}

.method {
  font-family: var(--mono);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: 500;
  padding: var(--s1) var(--s2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  display: inline-block;
}

.method.post {
  border-color: var(--ink);
}

.method.delete {
  border-color: var(--error);
  color: var(--error);
}

.list {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}

.row {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s4);
}

.rowhead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
  margin-bottom: var(--s2);
  flex-wrap: wrap;
}

.rowhead .name {
  font-weight: 600;
}

.rowbuttons {
  display: flex;
  gap: var(--s2);
  align-items: center;
  flex-wrap: wrap;
}

/* ---------------------------------------------------------- the library -- */

/* Folders sit in a folders beside the cards rather than as chips above them: a
   vertical list reads as a place you are in, chips read as a filter you applied.
   One level deep, so the folders never needs to indent. */

.withfolders {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: var(--s12);
  align-items: start;
}

@media (max-width: 900px) {
  .withfolders {
    grid-template-columns: 1fr;
    gap: var(--s6);
  }
}

.folders {
  display: flex;
  flex-direction: column;
  gap: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  position: sticky;
  /* The stage head sits outside the scrolling area now, so the only thing this
     has to clear is its own breathing room. */
  top: var(--s6);
}

.folderitem {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
  padding: var(--s3) var(--s4);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--muted);
  border-left: 2px solid transparent;
  border-bottom: 1px solid var(--line);
  transition: background-color var(--fast), color var(--fast);
}

.folderitem:hover {
  background: var(--tint);
  color: var(--ink);
}

.folderitem.on {
  color: var(--ink);
  font-weight: 600;
  border-left-color: var(--ink);
  background: var(--tint);
}

.foldercount {
  font-family: var(--mono);
  font-size: var(--fs-caption);
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  flex: none;
}

.folderitem .muted {
  color: var(--muted);
}

.folderform {
  display: flex;
  gap: var(--s2);
  padding: var(--s3) var(--s4);
}

.folderform input {
  margin-top: 0;
  width: auto;
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--fs-small);
  padding: var(--s2);
}

.foldertools {
  margin-bottom: var(--s6);
}

.foldertools input {
  flex: 0 1 260px;
}

.movefolder select {
  margin-top: 0;
  font-size: var(--fs-caption);
  padding: var(--s1) var(--s2);
  color: var(--muted);
}


.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--s5);
}

.templatecard {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s6);
  background: var(--surface);
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  transition: border-color var(--fast);
}

.templatecard:hover {
  border-color: var(--line-strong);
}

.templatecard .title {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: 600;
  color: var(--ink);
}

.templatecard .title:hover {
  color: var(--accent);
}

.templatecard .tid {
  font-family: var(--mono);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--muted);
}

.templatecard .small {
  margin-top: auto;
}

.figures {
  display: flex;
  gap: var(--s6);
  margin: 0;
}

.figures div {
  margin: 0;
}

.figures dt {
  font-family: var(--mono);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--muted);
  margin: 0;
}

.figures dd {
  margin: 0;
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-variant-numeric: tabular-nums;
}

/* -------------------------------------------------------------------- code -- */

pre.code {
  background: var(--tint);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s3) var(--s4);
  overflow-x: auto;
  font-family: var(--mono);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  margin: var(--s4) 0;
}

/* A thousand lines of sample JSON must not eat the page. */
.card pre.code {
  max-height: 420px;
  overflow: auto;
}

pre.code.big {
  font-size: var(--fs-small);
  background: var(--surface);
  border-color: var(--success);
}

.mailtext {
  background: var(--tint);
  border: 1px solid var(--line);
  padding: var(--s3) var(--s4);
  font-family: var(--mono);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  white-space: pre-wrap;
  margin: var(--s3) 0;
}

code.clip {
  font-size: var(--fs-caption);
  overflow-wrap: anywhere;
}

/* -------------------------------------------------------- plan and usage -- */

.planline {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  margin: 0 0 var(--s6);
  flex-wrap: wrap;
}

.planname {
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  font-weight: 600;
}

.usage {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--s6);
  margin-bottom: var(--s8);
}

.usagehead {
  display: flex;
  justify-content: space-between;
  gap: var(--s3);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  margin-bottom: var(--s2);
  font-variant-numeric: tabular-nums;
}

.meter {
  height: 4px;
  background: var(--line);
}

.meter span {
  display: block;
  height: 4px;
  background: var(--ink);
}

/* How full a bar is. This used to be a `style="width:..%"` on the span, which
   the Content-Security-Policy on these pages no longer allows, so the width
   comes out of a class in five percent steps. Both bars use it: the usage meter
   here and the one in the rail from app.css. */
.fill-0   { width: 0 }
.fill-5   { width: 5% }
.fill-10  { width: 10% }
.fill-15  { width: 15% }
.fill-20  { width: 20% }
.fill-25  { width: 25% }
.fill-30  { width: 30% }
.fill-35  { width: 35% }
.fill-40  { width: 40% }
.fill-45  { width: 45% }
.fill-50  { width: 50% }
.fill-55  { width: 55% }
.fill-60  { width: 60% }
.fill-65  { width: 65% }
.fill-70  { width: 70% }
.fill-75  { width: 75% }
.fill-80  { width: 80% }
.fill-85  { width: 85% }
.fill-90  { width: 90% }
.fill-95  { width: 95% }
.fill-100 { width: 100% }

.errortext {
  color: var(--error);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
}

/* --- a plan running out, in the rail --- */

/* The one thing in the chrome that has to be seen before it bites: the day the
   end date passes, every render stops. So it sits under the usage figures,
   where you already look for what your plan is doing, and it is a link to
   /billing, because the place that says it should be the place you fix it.
   The border on the left carries the same two colours as the notices on the
   pages, so a warning looks like a warning wherever you meet it. */
.railplan {
  display: block;
  margin-top: auto;
  padding: var(--s4) var(--s6);
  border-top: 1px solid #3a3b3e;
  border-left: 2px solid var(--info);
  text-decoration: none;
}

/* Directly under the usage figures it belongs to that block and not to a new
   one, so the line and the space between them go. The automatic top margin has
   to go with them: the usage block above has one too, and two of those in one
   column split the free space between themselves and leave the pair floating in
   the middle of the rail. */
.railusage + .railplan {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* app.css styles these two as blocks in the usage panel; inside a link they
   are spans, so they need saying again. */
.railplan .raillabel,
.railplan .railsub {
  display: block;
}

.railplan.ended {
  border-left-color: var(--error);
}

.railplan.ended .raillabel {
  color: var(--error);
}

.railplan:hover .railsub {
  color: var(--surface);
}

/* --- the traffic light on the admin screen --- */

.statuslist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

.statuslist li {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--muted);
}

.statuslist li::before {
  content: '';
  width: 8px;
  height: 8px;
  flex: none;
  background: var(--muted);
  transform: translateY(1px);
}

.statuslist li.ok::before {
  background: var(--success);
}

.statuslist li.broken::before {
  background: var(--error);
}

.statuslist li b {
  color: var(--ink);
  font-weight: 600;
}

/* Test against live is the one thing on the admin screen worth shouting, because
 * being wrong about it is invisible: every payment appears to work and no money
 * moves. */
.statusline {
  display: flex;
  gap: var(--s2);
  align-items: baseline;
  flex-wrap: wrap;
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--muted);
  border-left: 2px solid var(--line-strong);
  padding-left: var(--s3);
}

.statusline b {
  color: var(--ink);
}

.statusline.live {
  border-left-color: var(--success);
}

/* The brand's orange, the one that already means "busy, not finished" on a
   render. Test mode is exactly that state. */
.statusline.test {
  border-left-color: #ff7500;
}

/* --- one customer's agreement on the admin screen --- */
/*
 * Nine fields per organization do not fit on a row of a table, and a table that
 * squeezes them in is a table nobody reads. Shut, a customer is one line with
 * what you came to look at on it: what they use, what they are on, and what this
 * month costs them. Open, the whole agreement.
 */

.org {
  border-top: 1px solid var(--line);
  padding: var(--s3) 0;
}

.org:last-child {
  border-bottom: 1px solid var(--line);
}

.org > summary {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  flex-wrap: wrap;
  cursor: pointer;
  list-style: none;
}

.org > summary::-webkit-details-marker {
  display: none;
}

.org > summary::before {
  content: '+';
  font-family: var(--mono);
  color: var(--muted);
  width: 12px;
  flex: none;
}

.org[open] > summary::before {
  content: '–';
}

.org > summary .small {
  color: var(--muted);
}

/* The amount is the thing you scan down the list for, so it sits at the far end
 * of the line where the eye can run straight down it. */
.org > summary .amount {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
}

.org .tag {
  font-size: var(--fs-small);
  border: 1px solid var(--line);
  padding: 0 var(--s2);
  color: var(--muted);
}

.orgbody {
  padding: var(--s4) 0 var(--s2) var(--s5);
}

.preset {
  padding-bottom: var(--s4);
  border-bottom: 1px solid var(--line);
}

.preset select {
  flex: 0 1 200px;
}

.preset .small {
  color: var(--muted);
}

.terms {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--s3);
}

.termfield {
  font-weight: 400;
}

.termfield span {
  display: block;
  font-size: var(--fs-small);
  color: var(--muted);
}

.termfield input {
  font-variant-numeric: tabular-nums;
}

.table tr.total td {
  border-top: 2px solid var(--ink);
}

/* --------------------------------------------------------------- pricing -- */

.planrow {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--s5);
  margin: var(--s8) 0;
}

.plancard {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s6);
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s4);
  transition: border-color var(--fast);
}

.plancard:hover {
  border-color: var(--line-strong);
}

.plancard.featured {
  border-color: var(--ink);
}

.flag {
  position: absolute;
  top: -1px;
  right: -1px;
  background: var(--ink);
  color: var(--surface);
  font-family: var(--mono);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  padding: var(--s1) var(--s2);
}

.plancard h2 {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: 600;
  margin: 0;
}

.price {
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  margin: 0;
  font-variant-numeric: tabular-nums;
}

.price span {
  font-size: var(--fs-small);
  color: var(--muted);
}

.plancard ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--muted);
}

.plancard .primary,
.plancard .button {
  margin-top: auto;
  justify-content: center;
}

.notice a {
  color: inherit;
}

/* ----------------------------------------------------------- small screens -- */

/* Under 900px the rail cannot be a column any more. It becomes a strip across
   the top: logo, then the navigation scrolling sideways, with sign out at the
   end. The usage figures and the organization name drop out. They are
   reference, not navigation, and both have a page of their own. Signing out
   stays: taking away the way out of an account is never a saving. */
@media (max-width: 900px) {
  .shell {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
  }

  .rail {
    flex-direction: row;
    align-items: center;
    gap: var(--s4);
    padding: var(--s3) var(--gutter);
    overflow: hidden;
  }

  .raillogo {
    padding: 0;
  }

  /* The navigation is the only part that scrolls, so the mark and the way out
     stay put. It fades out at its right edge instead of cutting off, which is
     what tells you there is more of it. The mask sits on the nav and not on the
     rail, so it takes the labels with it and leaves the charcoal alone. */
  .railnav {
    flex: 1 1 auto;
    min-width: 0;
    flex-direction: row;
    gap: var(--s4);
    margin: 0;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
  }

  .railnav::-webkit-scrollbar {
    display: none;
  }

  .navgroup {
    flex-direction: row;
    gap: var(--s1);
    border: 0;
    padding: 0;
    margin: 0;
  }

  .navitem {
    padding: var(--s2) var(--s3);
    white-space: nowrap;
  }

  /* A left border means nothing in a horizontal strip. */
  .navitem.on {
    border-left: 0;
    border-bottom: 2px solid var(--accent);
  }

  .railusage,
  .railorg,
  .railmail,
  .railswitch {
    display: none;
  }

  /* The usage figures drop out of the strip, but a plan that has ended or is
     about to does not. That one is not reference you can look up later: it is
     the reason your renders are failing today. */
  .railplan {
    flex: none;
    margin: 0;
    padding: 0 0 0 var(--s3);
    border-top: 0;
    white-space: nowrap;
  }

  .railfoot {
    flex: none;
    margin: 0;
    padding: 0;
    border: 0;
    white-space: nowrap;
  }

  .stagehead {
    flex-wrap: wrap;
    gap: var(--s3);
  }

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