/* The application shell: the rail, the frame it holds, and paper.

   Before this, there was no shell. The map page and the day page each drew
   their own header, their own brand and their own sign out button, in two
   stylesheets, and nothing linked one to the other. The day page, where money
   is signed, could only be reached by typing its address. This file is the
   one frame every screen now sits inside.

   Two surfaces, and the typeface says which one you are on. Sans is the
   console: live, changing, watched for a shift. Serif is paper: settled,
   signed, printed and handed to somebody. That rule is the whole structural
   idea and it is not decorated anywhere else. */

/* ---------------------------------------------------------------- frame */

.shell {
  display: grid;
  grid-template-columns: var(--rail-collapsed) 1fr;
  min-height: 100dvh;
  background: var(--surface-0);
}

:root[data-rail="expanded"] .shell {
  grid-template-columns: var(--rail-expanded) 1fr;
}

/* The rail changing width must not animate the map underneath it, which
   repaints its whole canvas on every frame of a transition and stutters. */
@media (prefers-reduced-motion: no-preference) {
  .shell {
    transition: grid-template-columns 160ms ease;
  }
}

/* min-height 0, not 100dvh. As a grid item it already stretches to the
   shell's full height, and asking for a viewport's worth on top of that makes
   the column taller than the window by exactly the topline, which on the map
   screen pushed the map under its own header. min-width 0 for the same family
   of reason: a flex child defaults to its content's minimum width, and the
   map refuses to shrink without it. */
.shell__main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}

/* ----------------------------------------------------------------- rail */

.rail {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-2);
  background: var(--surface-1);
  border-right: 1px solid var(--border-subtle);
  overflow: hidden;
}

.rail__brand {
  display: flex;
  align-items: center;
  text-decoration: none;
  gap: var(--space-3);
  height: var(--tap);
  padding-left: var(--space-2);
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: var(--font-size-md);
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

/* The mark is the fleet's own shorthand, two letters, and it is the only
   thing left when the rail is collapsed. */
.rail__mark {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: var(--space-6);
  height: var(--space-6);
  border-radius: var(--radius-1);
  background: var(--accent-quiet);
  color: var(--text-primary);
  font-size: var(--font-size-sm);
  font-weight: 700;
}

.rail__wordmark {
  overflow: hidden;
  text-overflow: ellipsis;
}

.rail__nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-top: var(--space-4);
}

/* Pushed to the bottom rather than ordered after the nav, so setup and the
   signed in person sit where a person expects them however many sections
   the rail happens to hold for this role. */
.rail__foot {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-top: auto;
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-subtle);
}

.rail__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: var(--tap);
  padding: 0 var(--space-2);
  border-radius: var(--radius-1);
  color: var(--text-secondary);
  font-family: var(--font-ui);
  font-size: var(--font-size-md);
  text-decoration: none;
  white-space: nowrap;
}

.rail__item:hover {
  background: var(--surface-2);
  color: var(--text-primary);
}

.rail__item:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* The section you are in. Marked by a bar against the rail edge as well as
   by colour, because on a collapsed rail colour alone is one icon out of
   six looking slightly different from the others. */
.rail__item[aria-current="page"] {
  background: var(--surface-2);
  color: var(--text-primary);
  box-shadow: inset var(--space-1) 0 0 var(--accent);
}

.rail__icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: var(--space-6);
  height: var(--space-6);
}

.rail__icon svg {
  width: var(--space-5);
  height: var(--space-5);
  stroke: currentColor;
  stroke-width: 1.5;
  fill: none;
}

.rail__label {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* A count beside a section, for the one thing a rail should interrupt you
   about: days nobody has signed. Absent rather than zero, because a badge
   showing nothing to do is a badge people stop seeing. */
.rail__count {
  margin-left: auto;
  padding: 0 var(--space-2);
  border-radius: var(--radius-2);
  background: var(--status-alert-wash);
  color: var(--status-alert);
  font-size: var(--font-size-xs);
  font-variant-numeric: tabular-nums;
}

/* Collapsed, the labels are gone and the icon centres in its own row. The
   accessible name stays on the link, so a screen reader is unaffected by
   what is only a visual collapse. */
:root[data-rail="collapsed"] .rail__label,
:root[data-rail="collapsed"] .rail__wordmark,
:root[data-rail="collapsed"] .rail__count {
  display: none;
}

:root[data-rail="collapsed"] .rail__item,
:root[data-rail="collapsed"] .rail__brand {
  justify-content: center;
  padding-left: 0;
}

.rail__toggle {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: var(--tap);
  padding: 0 var(--space-2);
  border: 0;
  border-radius: var(--radius-1);
  background: none;
  color: var(--text-muted);
  font-family: var(--font-ui);
  font-size: var(--font-size-sm);
  cursor: pointer;
}

.rail__toggle:hover {
  background: var(--surface-2);
  color: var(--text-primary);
}

.rail__toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* -------------------------------------------------------------- topbar */

.topline {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: 56px;
  padding: var(--space-3) var(--space-5);
  background: var(--surface-1);
  border-bottom: 1px solid var(--border-subtle);
}

.topline__title {
  margin: 0;
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: var(--font-size-lg);
  font-weight: 600;
}

.topline__note {
  color: var(--text-muted);
  font-family: var(--font-ui);
  font-size: var(--font-size-sm);
}

.topline__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-left: auto;
}

/* Shown only on a phone, where the rail is a drawer rather than a column. */
.topline__menu {
  display: none;
  align-items: center;
  justify-content: center;
  width: var(--tap);
  height: var(--tap);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-1);
  background: var(--surface-2);
  color: var(--text-primary);
  cursor: pointer;
}

/* --------------------------------------------------------------- paper */

/* A document, laid on the console. Everything inside is serif, every figure
   is tabular, and it prints as what it already looks like. */
.paper {
  max-width: 68ch;
  margin: 0 auto;
  padding: var(--space-6);
  background: var(--paper-1);
  border: 1px solid var(--paper-edge);
  border-radius: var(--radius-2);
  color: var(--ink);
  font-family: var(--font-document);
  box-shadow: var(--shadow-2);
}

.paper + .paper {
  margin-top: var(--space-5);
}

.paper__head {
  padding-bottom: var(--space-4);
  border-bottom: 2px solid var(--ink);
}

.paper__title {
  margin: 0;
  font-size: var(--font-size-2xl);
  font-weight: 400;
  letter-spacing: -0.01em;
}

/* The line that says whose document this is and what period it covers.
   Sans, deliberately: it is metadata about the document rather than part of
   it, and the same distinction the whole interface runs on applies inside a
   page as well as between pages. */
.paper__meta {
  margin: var(--space-2) 0 0;
  color: var(--ink-secondary);
  font-family: var(--font-ui);
  font-size: var(--font-size-sm);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.paper__section {
  margin-top: var(--space-6);
}

.paper__heading {
  margin: 0 0 var(--space-3);
  color: var(--ink-secondary);
  font-family: var(--font-ui);
  font-size: var(--font-size-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

/* ------------------------------------------------------------- ledger */

/* The signature of this interface, and it is lifted from the group's own
   statements rather than invented: every line they type is a label, then a
   run of space, then a figure. Bal b/d. 220.00. Less fuel white today 200.

   Dot leaders are what makes that scannable when the label is long and the
   screen is narrow, which is a phone in a truck yard. The figures are
   tabular and right aligned so a column of money can be added by eye, which
   is the only thing a column of money is for. */
.ledger {
  margin: 0;
}

.ledger__row {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-2) 0;
}

.ledger__row + .ledger__row {
  border-top: 1px solid var(--paper-rule);
}

.ledger__label {
  flex: 0 1 auto;
  min-width: 0;
  font-size: var(--font-size-md);
}

.ledger__leader {
  flex: 1 1 auto;
  height: 1px;
  margin-bottom: var(--space-1);
  border-bottom: 1px dotted var(--paper-edge);
}

.ledger__figure {
  flex: 0 0 auto;
  font-family: var(--font-figure);
  font-size: var(--font-size-md);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* The line a person is actually looking for. Heavier rule above it, the way
   a total is ruled off in a cash book, and never a colour: a total is not a
   status. */
.ledger__row--total {
  margin-top: var(--space-2);
  padding-top: var(--space-3);
  border-top: 2px solid var(--ink);
}

.ledger__row--total .ledger__label,
.ledger__row--total .ledger__figure {
  font-weight: 700;
}

/* Owed to somebody, and not yet paid. The one figure on a dividend
   statement a director is actually reading for. */
.ledger__figure--outstanding {
  color: var(--status-alert);
}

/* --------------------------------------------------------- signed off */

/* What turns a page of figures into a document: who stood behind it and
   when. Empty is a statement too, and it says so in words rather than by
   being absent. */
.signature {
  display: flex;
  align-items: flex-end;
  gap: var(--space-4);
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--paper-rule);
}

.signature__rule {
  flex: 1 1 auto;
  border-bottom: 1px solid var(--ink);
}

.signature__who {
  font-size: var(--font-size-md);
}

.signature__when {
  color: var(--ink-muted);
  font-family: var(--font-ui);
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.signature--unsigned .signature__who {
  color: var(--ink-muted);
  font-style: italic;
}

/* ---------------------------------------------------------------- page */

.page {
  flex: 1 1 auto;
  padding: var(--space-6) var(--space-5);
  overflow-y: auto;
}

.page--flush {
  padding: 0;
  overflow: hidden;
}

/* ---------------------------------------------------------------- phone */

/* Below this the rail becomes a drawer. 64px of a 390px screen is a sixth
   of it spent on navigation, which is the crowding a collapsed rail exists
   to avoid in the first place. */
@media (max-width: 720px) {
  .shell,
  :root[data-rail="expanded"] .shell {
    grid-template-columns: 1fr;
  }

  .rail {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 40;
    width: var(--rail-expanded);
    transform: translateX(-100%);
    box-shadow: var(--shadow-2);
  }

  @media (prefers-reduced-motion: no-preference) {
    .rail {
      transition: transform 160ms ease;
    }
  }

  :root[data-drawer="open"] .rail {
    transform: translateX(0);
  }

  /* Labels always show in the drawer. A drawer that opens to icons is a
     drawer that opened for nothing. */
  :root[data-rail="collapsed"] .rail__label,
  :root[data-rail="collapsed"] .rail__wordmark {
    display: block;
  }

  :root[data-rail="collapsed"] .rail__item,
  :root[data-rail="collapsed"] .rail__brand {
    justify-content: flex-start;
    padding-left: var(--space-2);
  }

  .rail__toggle {
    display: none;
  }

  .topline__menu {
    display: flex;
  }

  .shell__scrim {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 30;
    background: var(--surface-0);
    opacity: 0.7;
  }

  .paper {
    padding: var(--space-4);
  }

  .page {
    padding: var(--space-4) var(--space-3);
  }
}

/* ---------------------------------------------------------------- print */

/* A statement is a document, and this is the whole reason the documents are
   paper rather than dark. Nothing here needs a second stylesheet: the
   chrome goes, the paper stays as it already looks. */
@media print {
  .rail,
  .topline,
  .shell__scrim {
    display: none;
  }

  .shell,
  :root[data-rail="expanded"] .shell {
    grid-template-columns: 1fr;
  }

  .page {
    padding: 0;
    overflow: visible;
  }

  .paper {
    max-width: none;
    border: 0;
    box-shadow: none;
  }
}

/* The toggle points the way the rail will move, so the control always
   describes what pressing it does rather than what state it is in. */
:root[data-rail="expanded"] .rail__chevron {
  transform: rotate(180deg);
}

/* A row in the rail that is not a destination: who is signed in. Same shape
   as its neighbours so the rail reads as one column, but nothing about it
   invites a press. */
.rail__item--static {
  color: var(--text-muted);
  cursor: default;
}

.rail__item--static:hover {
  background: none;
  color: var(--text-muted);
}

/* Sign out is a form because it is a POST, and the button inside it has to
   sit in the rail's column like everything else rather than looking like a
   button somebody dropped in. */
.rail__signout {
  margin: 0;
}

.rail__item--button {
  width: 100%;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
}

/* Present for a screen reader, absent for everyone else. Used on the icon
   only controls, which without it announce as "button" and nothing more. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  /* clip-path rather than the old clip plus negative margin trick, which
     needed a 1px offset the house spacing rule would reject and which this
     replaces outright. */
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
