/* ============================================================
   THE LEDGER BOOK
   The profit and loss statement, read like an owner.

   The module is a bound ledger. The masthead is the book's spine and
   its pasted cover label. Folio one is the front board rather than a
   page of it: green cloth, the label pasted at full size, and the
   frontispiece plate mounted beside it. Every screen after it is a
   ruled page, with a red
   margin rule down the left and pale green ruling across it. The
   counter is a folio. Tab strips are the thumb tabs cut into the
   fore-edge. Statements are ledger columns: a faint vertical rule
   between the description and the money, totals closed with a double
   rule. The ending is a closing entry with a wax seal on it.

   Self contained: no CDN, no build step, no network. Two families:

     Quinela      licensed display serif, shipped in assets/fonts.
                  It carries the cover label, the screen headings, the
                  oversized figures and the item lines.
     Site Sans    Neufilla, the licensed body grotesque, shipped as
                  WOFF version 1. Asked only ever to be plain.

   Color discipline worth knowing before editing:

     ink      #1A1A18 on cream #F3EBD9      14.7:1
     cream    #F3EBD9 on bottle green       10.2:1
     bottle   #123D2B on cream              10.2:1
     pencil   #5C5A52 on cream               5.8:1
     red      #B3261E on cream               5.5:1
     brass    #8A6A1F on cream               4.2:1  <- never text

   Brass is the one accent and it carries rules only: it fails 4.5:1
   on cream, so no word is ever set in it. Red carries negatives and
   the margin rule, and a negative figure never arrives without the
   minus glyph or the word beside it.

   The ruling is the green rule color at 0.6 alpha. That is not
   decoration hedging: at full strength the ruling would blend to a
   ground where red measures 4.39:1, and red figures sit on top of it.
   At 0.6 the worst case blend is #DAE0CC, where red measures 4.83:1,
   pencil 5.1:1 and ink 12.9:1. Do not raise the alpha.

   Layout discipline, unchanged from the navy build:
     The whole module is one fixed height stage. The document never
     scrolls at any size. The masthead is pinned at the top, the pager
     at the bottom, and the screen sits between them. At 900px wide by
     640px tall and up, nothing scrolls vertically at all: every screen
     restructures itself into columns, tabs, or sub-steps so that it
     fits. Below that, the masthead and pager stay put and only the
     screen scrolls. Tables may still scroll sideways in their wrapper.
   ============================================================ */

@font-face {
  font-family: 'Quinela';
  src: url('assets/fonts/Quinela-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Quinela';
  src: url('assets/fonts/Quinela-Italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: 'Quinela';
  src: url('assets/fonts/Quinela-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Quinela';
  src: url('assets/fonts/Quinela-Black.woff2') format('woff2');
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}

/* The body grotesque. Shipped as WOFF version 1, not WOFF2, so there is one
   src per face and no woff2 fallback to list. The middle weight is the
   family's semibold, mapped at 600, and the rules below ask for 600 rather
   than 500 so the file is actually used instead of being synthesized. */
@font-face {
  font-family: 'Site Sans';
  src: url('assets/fonts/sans-regular.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Site Sans';
  src: url('assets/fonts/sans-medium.woff') format('woff');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Site Sans';
  src: url('assets/fonts/sans-bold.woff') format('woff');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  --cream: #F3EBD9;
  --cream-2: #EBE1CC;
  --rule: #C9D8C4;
  --red: #B3261E;
  --bottle: #123D2B;
  --ink: #1A1A18;
  --pencil: #5C5A52;
  --brass: #8A6A1F;

  --hair: rgb(26 26 24 / 0.18);
  --hair-soft: rgb(26 26 24 / 0.10);
  --hair-brass: rgb(138 106 31 / 0.6);
  --hair-green: rgb(18 61 43 / 0.3);

  --serif: 'Quinela', Georgia, 'Times New Roman', serif;
  --sans: 'Site Sans', 'Helvetica Neue', Arial, system-ui, sans-serif;

  /* Figures in a money column, and only there. Neufilla as delivered has an
     empty GSUB and GPOS feature list, so there is no tnum for
     font-variant-numeric to switch on and its digits are proportional: at
     60px the 1 measures 16.75px against 37.5px for the 4. Down a column of
     money that shows up as thousands separators that do not line up, which
     is the one piece of craft this genre is actually judged on. So amount
     cells use the first face here that has monospaced digits by
     construction. It reaches digits, currency signs and separators inside
     td.num and nothing else: every word on the page, column headings
     included, stays in the licensed family. When Neufilla ships with
     tabular figures, delete the font-family line from td.num and the
     licensed face takes the column back. */
  --figures: 'Helvetica Neue', Arial, system-ui, sans-serif;

  --measure: 36rem;

  /* Stage spacing. Every one of these shrinks with the viewport so a 640px
     tall frame gives its height to the content and not to the gutters. */
  --pad-x: clamp(1rem, 2.2vw, 1.6rem);
  --gap-v: clamp(0.5rem, 1.4vh, 1rem);
  --gap-h: clamp(1.1rem, 2.4vw, 2.4rem);

  /* The ruling. One line per line of body copy, so the page reads as ruled
     paper rather than as a texture. Redeclared wherever the leading changes. */
  --ruling-step: 1.62rem;
  --ruling: rgb(201 216 196 / 0.6);
  --ruling-bg: repeating-linear-gradient(
    to bottom,
    rgb(0 0 0 / 0) 0,
    rgb(0 0 0 / 0) calc(var(--ruling-step) - 1px),
    var(--ruling) calc(var(--ruling-step) - 1px),
    var(--ruling) var(--ruling-step)
  );

  /* The spine down the left of the cover. */
  --spine-w: clamp(0.7rem, 1.5vw, 1.05rem);
}

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

html,
body {
  height: 100%;
}

html {
  background: var(--cream);
}

body {
  margin: 0;
  overflow: hidden;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-wrap: break-word;
}

/* One focus treatment: 2px bottle green, 3px offset. Inverted on the cover. */
:focus-visible {
  outline: 2px solid var(--bottle);
  outline-offset: 3px;
}

.masthead :focus-visible {
  outline-color: var(--cream);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

svg {
  display: block;
  max-width: 100%;
  height: auto;
}

/* ---------------------------------------------- the stage shell */

.frame {
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

#module {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  max-width: 68rem;
  margin: 0 auto;
  padding: var(--gap-v) var(--pad-x) 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* The margin rule. One red line down the left of the book block, inside the
   gutter, so no content moves to make room for it. */
#module::before {
  content: '';
  position: absolute;
  left: calc(var(--pad-x) * 0.4);
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--red);
  pointer-events: none;
}

/* Without JS every screen is simply printed in order down the page, and the
   one thing allowed to scroll is main. */
#module {
  overflow-y: auto;
}

.js #module {
  overflow: hidden;
}

.screen {
  position: relative;
  isolation: isolate;
  padding-bottom: 1rem;
}

/* The ruling itself, laid behind the page and nothing else. Sitting on a
   pseudo element rather than on the screen's own background is what lets it
   draw in from the margin on entry without touching a single measurement. */
.screen::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: var(--ruling-bg);
  transform-origin: left center;
  pointer-events: none;
}

.js .screen {
  display: none;
}

/* The current screen fills whatever the masthead and the pager leave, and
   scrolls inside itself only when the frame is too small for the deck rules
   to hold. */
.js .screen.is-current {
  display: block;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding-bottom: var(--gap-v);
}

/* ---------------------------------------------- masthead: spine and label */

.masthead {
  position: relative;
  flex: 0 0 auto;
  background: var(--bottle);
  color: var(--cream);
  border-bottom: 3px solid var(--brass);
}

/* The spine: a darker band of cloth with a line of brass stitching down it. */
.masthead::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--spine-w);
  background-image:
    linear-gradient(90deg, rgb(0 0 0 / 0.42), rgb(0 0 0 / 0) 78%),
    repeating-linear-gradient(to bottom, var(--brass) 0 5px, rgb(0 0 0 / 0) 5px 13px);
  background-size: 100% 100%, 2px 100%;
  background-position: 0 0, right 3px top 0;
  background-repeat: no-repeat, no-repeat;
  pointer-events: none;
}

.masthead-inner {
  max-width: 68rem;
  margin: 0 auto;
  padding: clamp(0.35rem, 0.95vh, 0.72rem) var(--pad-x)
           clamp(0.35rem, 0.95vh, 0.72rem)
           calc(var(--pad-x) + var(--spine-w));
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem 2rem;
}

.mast-title {
  min-width: 0;
}

/* The cover label: a cream card pasted onto the board, squared off, with a
   brass keyline and the shadow of a real label under it. */
.cover-label {
  display: inline-block;
  max-width: 100%;
  background: var(--cream);
  border: 1px solid var(--hair-brass);
  box-shadow: 0 1px 0 0 rgb(0 0 0 / 0.35);
  padding: clamp(0.2rem, 0.6vh, 0.36rem) clamp(0.6rem, 1.3vw, 0.95rem)
           clamp(0.24rem, 0.7vh, 0.42rem);
}

.eyebrow {
  margin: 0;
  max-width: none;
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.6rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--bottle);
}

h1 {
  margin: 0.1rem 0 0;
  max-width: 60ch;
  font-family: var(--serif);
  font-weight: 900;
  font-size: clamp(1.15rem, 2.05vw, 1.7rem);
  line-height: 1.08;
  letter-spacing: -0.014em;
  color: var(--ink);
}

/* ---------------------------------------------- the folio */

.progress {
  flex: 0 1 20rem;
  min-width: 11rem;
  display: flex;
  align-items: center;
  gap: 0.9rem;
}

.track {
  flex: 1 1 auto;
  height: 3px;
  background: rgb(243 235 217 / 0.9);
}

.track > span {
  display: block;
  height: 100%;
  width: 12.5%;
  background: var(--brass);
  transition: width 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}

.progress-text {
  flex: 0 0 auto;
  margin: 0;
  max-width: none;
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.66rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--cream);
  transform-origin: top center;
}

/* ---------------------------------------------- pager and footer */

/* The book closes on a double rule, the way a total does. */
.stage-foot {
  flex: 0 0 auto;
  width: 100%;
  max-width: 68rem;
  margin: 0 auto;
  padding: clamp(0.45rem, 1.1vh, 0.8rem) var(--pad-x) clamp(0.5rem, 1.3vh, 0.9rem);
  border-top: 4px double var(--bottle);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem 1.5rem;
}

.pager {
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

.pager .btn-solid,
.pager .btn-quiet {
  padding: 0.5rem 1.25rem;
}

.module-foot p {
  margin: 0;
  max-width: none;
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.62rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--pencil);
}

/* ---------------------------------------------- screen head and columns */

.screen-head > *:last-child {
  margin-bottom: 0;
}

.screen-body > * {
  min-width: 0;
}

.col {
  min-width: 0;
}

/* ---------------------------------------------- the cover

   Folio one is the front board of the book rather than a page of it: green
   cloth over board, the same brass stitching down the spine that the
   masthead carries, the cream label pasted on square, and the
   frontispiece plate mounted beside it. It is the one screen with no
   ruling behind it, because a cover is not a page. */

.cover-screen::before {
  display: none;
}

/* The red margin rule belongs to a page. On the cover the board covers the
   page, so the rule goes with it. Browsers without :has() keep the rule,
   which is a stray line and not a broken layout. */
.js #module:has(#screen-1.is-current)::before {
  display: none;
}

.board {
  position: relative;
  overflow: hidden;
  background-color: var(--bottle);
  background-image: linear-gradient(150deg, rgb(255 255 255 / 0.05), rgb(0 0 0 / 0.22));
  border: 1px solid var(--brass);
  padding: clamp(1rem, 3.2vh, 2rem) clamp(1rem, 2.6vw, 2.2rem)
           clamp(1rem, 3.2vh, 2rem)
           calc(var(--spine-w) + clamp(1rem, 2.6vw, 2.2rem));
  display: grid;
  gap: clamp(1rem, 2.4vw, 2rem);
  align-content: center;
}

.board::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--spine-w);
  background-image:
    linear-gradient(90deg, rgb(0 0 0 / 0.42), rgb(0 0 0 / 0) 78%),
    repeating-linear-gradient(to bottom, var(--brass) 0 5px, rgb(0 0 0 / 0) 5px 13px);
  background-size: 100% 100%, 2px 100%;
  background-position: 0 0, right 3px top 0;
  background-repeat: no-repeat, no-repeat;
  pointer-events: none;
}

/* The same pasted label as the masthead, at the size a title deserves. */
.board-label {
  align-self: center;
  background: var(--cream);
  border: 1px solid var(--hair-brass);
  box-shadow: 0 2px 0 0 rgb(0 0 0 / 0.35);
  padding: clamp(0.9rem, 2.6vh, 1.6rem) clamp(1.1rem, 2.4vw, 1.9rem)
           clamp(0.8rem, 2.2vh, 1.35rem);
}

.cover-kicker {
  margin: 0;
  max-width: none;
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.62rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--bottle);
}

.cover-screen h2 {
  margin: 0.45rem 0 0;
  padding-top: 0;
  max-width: 20ch;
  font-size: clamp(1.85rem, 4.6vw, 3.1rem);
  line-height: 1.02;
  color: var(--ink);
}

/* The board carries the brass here. A rule over the title would be a
   second one on the same card. */
.cover-screen h2::before {
  display: none;
}

.cover-promise {
  margin: 0.7rem 0 0;
  max-width: 36ch;
  font-family: var(--serif);
  font-size: clamp(1rem, 1.5vw, 1.2rem);
  line-height: 1.4;
  color: var(--ink);
}

/* The colophon line, where a printer puts the extent of a book. */
.cover-meta {
  margin: clamp(0.75rem, 2vh, 1.1rem) 0 0;
  padding-top: 0.55rem;
  border-top: 2px solid var(--brass);
  max-width: none;
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.64rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--pencil);
}

.board-plate {
  align-self: center;
  margin-bottom: 0;
}

/* ---------------------------------------------- type */

h2 {
  margin: 0 0 0.8rem;
  max-width: 20ch;
  font-family: var(--serif);
  font-weight: 900;
  font-size: clamp(1.5rem, 3vw, 2.2rem);
  line-height: 1.06;
  letter-spacing: -0.014em;
  color: var(--bottle);
  position: relative;
  padding-top: 1rem;
}

/* The one brass rule on the page, opening every screen. */
h2::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 4rem;
  height: 3px;
  background: var(--brass);
  transform-origin: left center;
  animation: rule-in 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes rule-in {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

h3 {
  margin: 1.4rem 0 0.55rem;
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--pencil);
}

.col > h3:first-child,
.tabpanel > h3:first-child {
  margin-top: 0;
}

/* The two headings that are questions rather than labels: they keep the
   sentence case and the size of running text. */
.qh {
  margin: 0 0 0.75rem;
  font-family: var(--sans);
  font-weight: 700;
  font-size: 1.02rem;
  line-height: 1.4;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
}

/* Present only for the no-JS reading order: with JS the tab itself carries
   the label, and repeating it inside the panel wastes a line of the stage. */
.js .nojs-h {
  display: none;
}

p {
  margin: 0 0 var(--gap-v);
  max-width: var(--measure);
}

.lead {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.02rem, 1.5vw, 1.2rem);
  line-height: 1.42;
  color: var(--ink);
  max-width: 44rem;
}

strong,
b {
  font-weight: 700;
}

ul,
ol {
  max-width: var(--measure);
  margin: 0 0 var(--gap-v);
  padding-left: 1.3rem;
}

li {
  margin-bottom: 0.45rem;
}

li::marker {
  color: var(--pencil);
}

.ticks {
  list-style: none;
  padding-left: 0;
}

.ticks > li {
  position: relative;
  padding-left: 1.5rem;
}

/* A ledger tick, not a rule: a short horizontal line in this position reads
   as a dash, and this house does not set dashes. */
.ticks > li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.5em;
  width: 0.8rem;
  height: 0.8rem;
  background: var(--brass);
  clip-path: polygon(18% 48%, 8% 60%, 40% 90%, 92% 22%, 80% 12%, 38% 66%);
}

.note,
.setup,
.aside,
.disclaimer,
.intro {
  max-width: var(--measure);
  font-size: 0.94rem;
  line-height: 1.55;
}

.note {
  border-left: 2px solid var(--rule);
  padding: 0.1rem 0 0.1rem 0.95rem;
  color: var(--pencil);
}

.setup {
  border-left: 3px solid var(--red);
  padding: 0.2rem 0 0.2rem 0.95rem;
  font-size: 0.98rem;
  color: var(--ink);
  max-width: 44rem;
}

.aside {
  margin-top: 1rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--hair-brass);
  color: var(--pencil);
  font-style: italic;
  font-family: var(--serif);
  font-size: 1.02rem;
}

.disclaimer {
  margin-top: 0.9rem;
  color: var(--pencil);
  font-size: 0.86rem;
}

.ask {
  margin-bottom: 0.6rem;
}

.caption,
figcaption {
  max-width: var(--measure);
  font-size: 0.84rem;
  line-height: 1.5;
  color: var(--pencil);
}

/* ---------------------------------------------- side column furniture */

/* A photograph pasted onto the page: a cream mount inside a brass keyline,
   and the picture itself pulled toward the bottle green of the binding. */
.photo {
  background-color: var(--cream);
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  border: 1px solid var(--hair-brass);
  box-shadow: inset 0 0 0 5px var(--cream);
  margin-bottom: 0.9rem;
}

/* Each panel carries the aspect ratio of the file that sits in it, so cover
   crops the edges rather than half the frame. Change the file, change the
   ratio. On the stage the ratio gives way: the photo becomes the one thing
   in a side column that flexes, so a long note never pushes anything off. */

.photo-hero {
  aspect-ratio: 16 / 11;
  background-image:
    linear-gradient(160deg, rgb(18 61 43 / 0.6), rgb(18 61 43 / 0.9)),
    url('assets/img/hero.jpg');
  background-blend-mode: multiply, normal;
}

.photo-ledger,
.photo-owner,
.photo-storefront {
  background-blend-mode: multiply, normal;
}

.photo-ledger {
  aspect-ratio: 3 / 2;
  background-image:
    linear-gradient(155deg, rgb(18 61 43 / 0.4), rgb(18 61 43 / 0.72)),
    url('assets/img/ledger.jpg');
}

.photo-owner {
  aspect-ratio: 3 / 2;
  background-image:
    linear-gradient(155deg, rgb(18 61 43 / 0.4), rgb(18 61 43 / 0.72)),
    url('assets/img/owner.jpg');
}

.photo-storefront {
  aspect-ratio: 2 / 3;
  background-image:
    linear-gradient(160deg, rgb(18 61 43 / 0.4), rgb(18 61 43 / 0.72)),
    url('assets/img/storefront.jpg');
}

/* The fifth slot, on screen seven, waiting for a photograph of the book itself.
   Two edits fill it and no others: point --book-img at the file, and raise
   --book-tone to 0.4 and 0.72 so the picture takes the same green duotone as
   the other four.

   The image is named through a custom property rather than written into the
   url() directly so that an empty slot asks the network for nothing: a bare
   url() to a file that is not there yet would put a 404 in the console every
   time a learner reached this screen. Empty, the slot is ruled cream, which
   is what a blank page in this book looks like. */
.photo-book {
  --book-img: none;
  --book-tone-a: 0.06;
  --book-tone-b: 0.14;
  aspect-ratio: 3 / 2;
  background-image:
    linear-gradient(155deg,
      rgb(18 61 43 / var(--book-tone-a)),
      rgb(18 61 43 / var(--book-tone-b))),
    var(--book-img),
    var(--ruling-bg);
  background-size: cover, cover, auto;
  background-position: center, center, 0 0;
  background-repeat: no-repeat, no-repeat, repeat;
  background-blend-mode: multiply, normal, normal;
}

.factbox {
  margin: 0;
  border-top: 1px solid var(--bottle);
}

.factbox > div {
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  padding: 0.45rem 0;
  border-bottom: 1px solid var(--hair-soft);
}

.factbox dt {
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.64rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pencil);
  padding-top: 0.15rem;
}

.factbox dd {
  margin: 0;
  text-align: right;
  font-size: 0.86rem;
  line-height: 1.4;
  color: var(--ink);
}

.pullquote {
  border-top: 3px solid var(--brass);
  padding-top: 0.75rem;
  margin-bottom: 0.9rem;
}

.pullquote p {
  margin: 0;
  font-family: var(--serif);
  font-weight: 700;
  font-size: 1.12rem;
  line-height: 1.26;
  color: var(--bottle);
}

/* ---------------------------------------------- ledger columns */

.table-wrap {
  overflow-x: auto;
  margin: 0 0 var(--gap-v);
  border-top: 2px solid var(--bottle);
}

.table-wrap:focus-visible {
  outline: 2px solid var(--bottle);
  outline-offset: 2px;
}

/* Two column statements read fine narrow; the three and four column
   tables need more before the headings start stacking. */
table {
  width: 100%;
  min-width: 18rem;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
  font-size: 0.95rem;
}

caption {
  caption-side: bottom;
  padding-top: 0.55rem;
  text-align: left;
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--pencil);
}

thead th {
  padding: 0.4rem 0.7rem;
  border-bottom: 1px solid var(--hair);
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.64rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pencil);
  text-align: left;
  vertical-align: bottom;
}

tbody th {
  text-align: left;
  font-weight: 400;
  color: var(--ink);
}

td,
tbody th {
  padding: 0.42rem 0.7rem;
  border-bottom: 1px solid var(--hair-soft);
  vertical-align: top;
  line-height: 1.4;
}

th:first-child,
td:first-child {
  padding-left: 0;
}

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

.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* The ledger's vertical rule: description on one side of it, money on the
   other, one rule per money column. */
.pnl th.num,
.pnl td.num {
  border-left: 1px solid var(--rule);
  padding-left: 0.85rem;
}

/* Figures must not break. Column headings must, or a four column table
   holds itself wider than the stage gives it and scrolls sideways for the
   sake of two words. */
thead th.num {
  white-space: normal;
}

td.num {
  font-family: var(--figures);
}

/* A negative in a money column is red, and never on its own: the row header
   says "Less", the cell carries the true minus sign, and a hidden word says
   "negative" to anyone reading the column aloud. */
td.less,
#v-cogs,
#v-opex {
  color: var(--red);
  font-weight: 700;
}

/* A subtotal row has no change of its own. That is a word, not a dash: a
   dash in a figure column is read aloud as nothing at all. */
td.nochange {
  font-family: var(--sans);
  font-size: 0.85rem;
  color: var(--pencil);
}

.pnl .row-indent th {
  padding-left: 1.4rem;
  color: var(--pencil);
  font-size: 0.89rem;
}

.pnl .row-indent td {
  color: var(--pencil);
  font-size: 0.89rem;
}

/* A subtotal is ruled off above. A total is closed with the double rule
   underneath it, which is the one piece of punctuation every ledger in the
   world agrees on. */
.pnl .row-sub th,
.pnl .row-sub td,
.pnl .row-group th,
.pnl .row-group td {
  font-weight: 700;
}

.pnl .row-sub th,
.pnl .row-sub td {
  border-top: 1px solid var(--ink);
  border-bottom-color: var(--hair);
}

.pnl .row-total th,
.pnl .row-total td {
  font-weight: 700;
  border-top: 1px solid var(--ink);
  border-bottom: 4px double var(--ink);
  font-size: 1.02rem;
}

#screen-4 table,
#wf-table table {
  min-width: 20rem;
}

.compact td,
.compact tbody th {
  padding-top: 0.38rem;
  padding-bottom: 0.38rem;
}

/* row entry animation, one after another. Transform only: a fade would drop
   every figure below its contrast ratio on the way in. */
.animate-rows .row-line {
  animation: row-in 0.34s cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes row-in {
  from { transform: translateX(-10px); }
  to { transform: none; }
}

/* ---------------------------------------------- signed figures */

.fig {
  white-space: nowrap;
  font-weight: 700;
}

.fig.pos { color: var(--bottle); }
.fig.neg { color: var(--red); }

/* Color is the third signal, never the first. The word is first, this glyph
   is second, and it is decoration as far as the accessibility tree is
   concerned because the word beside it already says the same thing. */
.fig.pos::before,
.fig.neg::before {
  content: '';
  display: inline-block;
  width: 0.66em;
  height: 0.66em;
  margin-right: 0.34em;
  vertical-align: -0.02em;
  background: currentColor;
}

.fig.pos::before {
  clip-path: polygon(18% 48%, 8% 60%, 40% 90%, 92% 22%, 80% 12%, 38% 66%);
}

.fig.neg::before {
  clip-path: polygon(4% 40%, 96% 40%, 96% 60%, 4% 60%);
}

.fig .tag {
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.64rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* ---------------------------------------------- the "what this means" toggles */

.why {
  display: inline-block;
  margin-left: 0.5rem;
  padding: 0.1rem 0.45rem;
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pencil);
  background: transparent;
  border: 1px solid var(--hair);
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}

.why:hover {
  color: var(--bottle);
  border-color: var(--bottle);
}

.why::after {
  content: ' +';
}

.why[aria-expanded="true"] {
  color: var(--cream);
  border-color: var(--bottle);
  background: var(--bottle);
}

.why[aria-expanded="true"]::after {
  content: ' \2212';
}

/* The notes panel: one line's explanation at a time, off to the side, so
   opening one never pushes the statement off the stage. */

.notes-panel {
  border-top: 2px solid var(--bottle);
  padding-top: 0.7rem;
  margin-bottom: 0.9rem;
}

.notes-panel .panel-title {
  margin-bottom: 0.7rem;
  border-bottom: 0;
  padding-bottom: 0;
}

.panel-hint {
  margin: 0;
  max-width: none;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--pencil);
}

.note-body {
  border-left: 3px solid var(--brass);
  padding-left: 0.9rem;
}

.note-body p {
  max-width: none;
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--pencil);
}

.note-line {
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--bottle) !important;
  margin-bottom: 0.35rem !important;
}

/* no-JS: every note is printed under the statement, in order */
.note-body + .note-body {
  margin-top: 0.9rem;
}

/* ---------------------------------------------- charts */

.chart-figure {
  margin: 0 0 var(--gap-v);
  padding-top: 0.85rem;
  border-top: 1px solid var(--hair-brass);
}

.chart-figure figcaption {
  margin-top: 0.6rem;
}

.chart .axis line {
  stroke: var(--hair);
  stroke-width: 1;
}

.chart .bar {
  fill: var(--bottle);
  transition: width 0.55s cubic-bezier(0.16, 1, 0.3, 1);
}

.chart .bar-b {
  fill: rgb(18 61 43 / 0.55);
}

.chart .bar-name {
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 700;
  fill: var(--ink);
}

.chart .bar-val {
  font-family: var(--figures);
  font-size: 15px;
  font-weight: 700;
  fill: var(--ink);
  font-variant-numeric: tabular-nums;
}

.chart .axis-label {
  font-family: var(--sans);
  font-size: 12px;
  fill: var(--pencil);
}

.timeline-figure {
  margin: 0.5rem 0 0;
}

.timeline .tl-axis {
  stroke: var(--hair);
  stroke-width: 2;
}

.timeline .tl-mark line {
  stroke: var(--bottle);
  stroke-width: 2;
}

.timeline .tl-mark circle {
  fill: var(--cream);
  stroke: var(--bottle);
  stroke-width: 2;
}

.timeline .tl-cash line {
  stroke: var(--red);
}

.timeline .tl-cash circle {
  stroke: var(--red);
  fill: var(--red);
}

.timeline text {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 700;
  fill: var(--ink);
}

.timeline .tl-sub {
  font-weight: 400;
  font-size: 11px;
  fill: var(--pencil);
}

.timeline .tl-spread rect {
  fill: rgb(18 61 43 / 0.2);
}

.waterfall-figure {
  border-top: 2px solid var(--bottle);
}

/* Left to fill the column the chart scales up and the bars turn into slabs.
   Capped on both axes: the height cap is what keeps the last screen on the
   stage at 640px. */
.waterfall {
  width: auto;
  max-width: min(100%, 44rem);
  max-height: min(21rem, 40vh);
  margin: 0 auto;
}

.waterfall .wf-base {
  stroke: var(--bottle);
  stroke-width: 1;
}

.waterfall rect {
  transform-box: fill-box;
  transform-origin: center bottom;
}

/* Green is money the business keeps, red is money that leaves, and the
   subtotal is the same green held back. Every bar is labeled in words and
   repeated in the table, so no meaning rests on the color alone. */
.bar-navy { fill: var(--bottle); }
.bar-slate { fill: rgb(18 61 43 / 0.55); }
.bar-red { fill: var(--red); }
.bar-green { fill: var(--bottle); }

.waterfall .wf-val {
  font-family: var(--figures);
  font-size: 13px;
  font-weight: 700;
  fill: var(--ink);
  font-variant-numeric: tabular-nums;
}

.waterfall .wf-name {
  font-family: var(--sans);
  font-size: 12px;
  fill: var(--pencil);
}

.waterfall .wf-foot {
  font-family: var(--sans);
  font-size: 12px;
  font-style: italic;
  fill: var(--pencil);
}

.animate-wf .wf-bar rect {
  animation: wf-rise 0.4s cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes wf-rise {
  from { transform: scaleY(0); }
  to { transform: scaleY(1); }
}

/* ---------------------------------------------- the simulator */

.sim {
  display: grid;
  gap: var(--gap-h);
  align-items: start;
}

.panel-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  border-bottom: 2px solid var(--bottle);
  margin-bottom: 0.8rem;
  padding-bottom: 0.4rem;
}

.panel-head .panel-title {
  margin: 0;
  border-bottom: 0;
  padding-bottom: 0;
}

.panel-title {
  margin: 0 0 0.9rem;
  padding-bottom: 0.4rem;
  border-bottom: 2px solid var(--bottle);
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.66rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--bottle);
  max-width: none;
}

.slider-grid {
  display: grid;
  gap: 0.7rem 1.5rem;
}

.slider-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  margin-bottom: 0.2rem;
}

.slider label {
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.82rem;
  line-height: 1.3;
  color: var(--ink);
}

.slider output {
  font-family: var(--serif);
  font-weight: 700;
  font-size: 1.14rem;
  font-variant-numeric: tabular-nums;
  color: var(--bottle);
  white-space: nowrap;
}

input[type="range"] {
  width: 100%;
  margin: 0;
  accent-color: var(--bottle);
  cursor: pointer;
}

input[type="range"]:focus-visible {
  outline: 2px solid var(--bottle);
  outline-offset: 4px;
}

.slider-hint {
  margin: 0.15rem 0 0;
  max-width: none;
  font-size: 0.78rem;
  line-height: 1.35;
  color: var(--pencil);
}

.bigfigs {
  display: grid;
  gap: 0.8rem 1.4rem;
  margin-top: 0.6rem;
}

@media (min-width: 34rem) {
  .bigfigs {
    grid-template-columns: 1fr 1fr;
  }
}

.bigfig {
  border-top: 3px solid var(--brass);
  padding-top: 0.55rem;
}

.bigfig-label {
  margin: 0;
  max-width: none;
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.64rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--pencil);
}

/* The two figures the whole screen is about, set in the display face at the
   size a ledger writes a total. */
.bigfig-value {
  margin: 0.06rem 0 0.22rem;
  max-width: none;
  font-family: var(--serif);
  font-weight: 900;
  font-size: clamp(1.75rem, 3.7vw, 2.55rem);
  line-height: 0.98;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--bottle);
}

.bigfig-note {
  margin: 0;
  max-width: none;
  font-size: 0.82rem;
  line-height: 1.4;
  color: var(--pencil);
}

/* The instruction and its button share a line, so the verdict underneath
   gets the height it needs without the panel growing. */
.prompt {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0 1.2rem;
  align-items: start;
}

.prompt p {
  max-width: none;
  margin-bottom: 0;
}

.prompt .feedback {
  grid-column: 1 / -1;
}

/* ---------------------------------------------- index tabs

   The thumb tabs cut into the fore-edge of a real ledger: squared, butted up
   against the edge of the block, alternating a shade the way a printer
   alternates board stock so the eye can count them. The one you are on is
   inked. */

.tabstrip {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  border-bottom: 2px solid var(--bottle);
}

/* With JS off there is nothing for a tab to do, so the strip goes and every
   panel prints in order with its own heading. */
.tabstrip {
  display: none;
}

.js .tabstrip {
  display: flex;
}

.tab {
  font-family: var(--sans);
  font-size: 0.67rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--pencil);
  background: var(--cream);
  border: 1px solid var(--hair);
  border-bottom: 0;
  border-radius: 0;
  padding: 0.42rem 0.75rem;
  margin-bottom: -2px;
  cursor: pointer;
  transition: color 0.18s ease, background 0.18s ease, border-color 0.18s ease;
}

.tabstrip .tab:nth-child(even) {
  background: var(--cream-2);
}

.tab:hover {
  color: var(--bottle);
  border-color: var(--bottle);
}

.tab[aria-selected="true"],
.tabstrip .tab[aria-selected="true"]:nth-child(even) {
  color: var(--cream);
  background: var(--bottle);
  border-color: var(--bottle);
  border-bottom: 2px solid var(--bottle);
}

.tabpanel {
  padding-top: 0.6rem;
}

.tabpanel:focus-visible {
  outline: 2px solid var(--bottle);
  outline-offset: 2px;
}

/* ---------------------------------------------- sub-steps */

.steps-nav {
  margin-top: 0.7rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--hair-brass);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem 1.2rem;
}

/* With JS off every item is on the page already, so the pager would lie. */
.steps-nav {
  display: none;
}

.js .steps-nav {
  display: flex;
}

.steps-move {
  display: flex;
  align-items: center;
  gap: 0.8rem;
}

.steps-count {
  margin: 0;
  max-width: none;
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pencil);
}

.step + .step {
  margin-top: 1.4rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--hair-soft);
}

/* ---------------------------------------------- choices */

.options {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  margin: 0 0 var(--gap-v);
  max-width: 46rem;
}

.options.tight {
  gap: 0.45rem;
}

.options-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.6rem;
  max-width: none;
}

@media (min-width: 40rem) {
  .options-grid {
    grid-template-columns: 1fr 1fr;
  }
}

.choice {
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  color: var(--ink);
  background: var(--cream);
  border: 1px solid var(--hair);
  border-left: 3px solid var(--rule);
  border-radius: 0;
  padding: 0.65rem 0.9rem;
  cursor: pointer;
  transition: border-color 0.18s ease, background 0.18s ease;
}

.choice:hover {
  border-color: var(--pencil);
  border-left-color: var(--bottle);
}

.choice[aria-pressed="true"] {
  border-color: var(--bottle);
  border-left-width: 3px;
  border-left-color: var(--bottle);
  background: var(--cream-2);
}

.choice-tag {
  display: block;
  margin-bottom: 0.2rem;
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--pencil);
}

.choice-body {
  display: block;
  line-height: 1.5;
}

/* ---------------------------------------------- the sorter */

.item {
  margin: 0 0 0.6rem;
  max-width: none;
  font-family: var(--serif);
  font-weight: 700;
  font-size: clamp(1.1rem, 2.2vw, 1.35rem);
  line-height: 1.24;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
}

.sort-btns {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.sort {
  font-family: var(--sans);
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--ink);
  background: var(--cream);
  border: 1px solid var(--hair);
  border-radius: 0;
  padding: 0.45rem 0.8rem;
  cursor: pointer;
  transition: border-color 0.18s ease, background 0.18s ease, color 0.18s ease;
}

.sort:hover {
  border-color: var(--bottle);
  background: var(--cream-2);
}

/* An answered item is stamped: the ledger's own ink, filled. */
.sort[aria-pressed="true"] {
  color: var(--cream);
  background: var(--bottle);
  border-color: var(--bottle);
  border-width: 2px;
  padding: calc(0.45rem - 1px) calc(0.8rem - 1px);
}

.sort[aria-pressed="true"]:hover {
  background: var(--bottle);
}

/* ---------------------------------------------- feedback */

.feedback {
  margin: 0.55rem 0 0;
  max-width: 46rem;
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--ink);
}

.feedback:empty {
  margin: 0;
}

.feedback:not(:empty) {
  padding-left: 0.85rem;
  border-left: 3px solid var(--pencil);
}

.feedback.is-right:not(:empty) { border-left-color: var(--bottle); }
.feedback.is-wrong:not(:empty) { border-left-color: var(--red); }

.feedback .glyph {
  display: inline-flex;
  width: 1.05em;
  height: 1.05em;
  vertical-align: -0.16em;
  margin-right: 0.35em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.feedback .verdict {
  font-weight: 700;
}

.feedback.is-right .glyph,
.feedback.is-right .verdict { color: var(--bottle); }

.feedback.is-wrong .glyph,
.feedback.is-wrong .verdict { color: var(--red); }

.feedback .fb-note {
  display: block;
  margin-top: 0.35rem;
  color: var(--pencil);
  font-size: 0.88rem;
}

.score {
  margin: 0;
  max-width: none;
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pencil);
}

/* ---------------------------------------------- takeaway */

.takeaway,
.scorecard {
  margin: 0 0 var(--gap-v);
  padding: 0.9rem 1.1rem 0.8rem;
  border: 1px solid var(--hair);
  border-top: 3px solid var(--brass);
  max-width: 46rem;
}

.takeaway-list {
  max-width: none;
  margin: 0;
  padding-left: 1.15rem;
}

.takeaway-list > li {
  margin-bottom: 0.55rem;
  line-height: 1.5;
  font-size: 0.95rem;
}

.takeaway-foot {
  margin: 0.75rem 0 0;
  padding-top: 0.7rem;
  border-top: 1px solid var(--hair-soft);
  max-width: none;
  font-family: var(--serif);
  font-style: italic;
  font-size: 1rem;
  line-height: 1.45;
  color: var(--pencil);
}

.scorelist {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: none;
}

.scorelist > li {
  padding: 0.45rem 0;
  border-bottom: 1px solid var(--hair-soft);
  font-size: 0.92rem;
  line-height: 1.45;
}

.scorelist > li:last-child {
  border-bottom: 0;
}

.restart-row {
  margin: 0;
}

/* ---------------------------------------------- buttons */

.btn-solid,
.btn-quiet {
  display: inline-block;
  font-family: var(--sans);
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border-radius: 0;
  padding: 0.6rem 1.3rem;
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}

.btn-small {
  font-size: 0.68rem;
  padding: 0.45rem 0.95rem;
  letter-spacing: 0.12em;
}

/* The one place brass carries weight rather than a word: a hairline of it
   under the primary button, the way a total is underlined. */
.btn-solid {
  color: var(--cream);
  background: var(--bottle);
  border: 1px solid var(--bottle);
  box-shadow: 0 2px 0 0 var(--brass);
}

.btn-solid:hover {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--cream);
}

.btn-quiet {
  color: var(--bottle);
  background: transparent;
  border: 1px solid var(--bottle);
}

.btn-quiet:hover {
  background: var(--bottle);
  color: var(--cream);
}

figcaption .btn-quiet {
  margin-top: 0.45rem;
}

button[disabled] {
  opacity: 0.35;
  cursor: default;
}

button[disabled]:hover {
  background: transparent;
  color: var(--bottle);
  border-color: var(--bottle);
}

.btn-solid[disabled]:hover {
  background: var(--bottle);
  color: var(--cream);
}

/* ---------------------------------------------- the closing entry

   The ending is the last page of the book: ruled cream with the red margin
   rule down it, the scores set as a closing entry, the takeaway sitting
   under a double rule where a total sits, a brass rule under that, and the
   wax seal pressed beside the heading.

   The dialog itself is only a positioning box, with no padding of its own,
   so a click that lands on it is a click on the backdrop and nothing else.
   ------------------------------------------------------------ */

#done {
  width: min(34rem, calc(100vw - 2.5rem));
  max-height: calc(100vh - 2rem);
  margin: auto;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  overflow: auto;
}

#done::backdrop {
  background: rgb(18 61 43 / 0.88);
}

.done-card {
  position: relative;
  background-color: var(--cream);
  background-image: var(--ruling-bg);
  border: 1px solid var(--hair);
  border-top: 4px solid var(--bottle);
  padding: clamp(0.95rem, 2.4vh, 1.5rem) clamp(1.1rem, 2.6vw, 1.8rem)
           clamp(0.85rem, 2vh, 1.3rem) clamp(1.5rem, 3.4vw, 2.4rem);
}

.done-card::before {
  content: '';
  position: absolute;
  left: clamp(0.6rem, 1.3vw, 0.95rem);
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--red);
  pointer-events: none;
}

/* The seal and the heading share a line, the way a stamp sits beside a
   signature. */
.done-crest {
  display: flex;
  align-items: center;
  gap: clamp(0.6rem, 1.8vw, 1rem);
  margin-bottom: 0.55rem;
}

.done-crest > div {
  min-width: 0;
}

.seal {
  flex: 0 0 auto;
  width: clamp(2.5rem, 6.5vw, 3.5rem);
  height: auto;
  transform-origin: center;
}

.seal-wax { fill: var(--bottle); }
.seal-ring { fill: none; stroke: var(--cream); stroke-width: 1.4; opacity: 0.75; }
.seal-mark { fill: none; stroke: var(--cream); stroke-width: 3.6; stroke-linecap: round; stroke-linejoin: round; }

.done-eyebrow {
  margin: 0;
  max-width: none;
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  line-height: 1.4;
  text-transform: uppercase;
  color: var(--pencil);
}

#done h2 {
  margin: 0.3rem 0 0;
  max-width: none;
  padding-top: 0;
  font-size: clamp(1.6rem, 3.2vw, 2.15rem);
}

/* The heading inside the card does not repeat the brass rule: the seal is
   the mark on this page. */
#done h2::before {
  display: none;
}

.done-say {
  margin: 0 0 0.85rem;
  max-width: none;
  font-family: var(--serif);
  font-size: 1.02rem;
  line-height: 1.42;
  color: var(--ink);
}

.done-heading {
  margin-bottom: 0;
  padding-bottom: 0.35rem;
  border-bottom: 0;
}

/* A closing entry: label left, figure right, ruled like the real one. */
.done-figures {
  margin: 0;
  border-top: 2px solid var(--bottle);
}

.done-figures > div {
  display: flex;
  gap: 1rem;
  align-items: baseline;
  justify-content: space-between;
  padding: 0.38rem 0;
  border-bottom: 1px solid var(--hair-soft);
}

.done-figures dt {
  font-family: var(--sans);
  font-weight: 700;
  font-size: 0.64rem;
  letter-spacing: 0.16em;
  line-height: 1.4;
  text-transform: uppercase;
  color: var(--pencil);
}

.done-figures dd {
  margin: 0;
  text-align: right;
  font-family: var(--figures);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 0.95rem;
  line-height: 1.4;
  color: var(--ink);
  white-space: nowrap;
}

/* The takeaway sits where a total sits: single rule above, double rule below. */
.done-figures .done-watch {
  border-top: 1px solid var(--ink);
  border-bottom: 4px double var(--ink);
  padding-bottom: 0.38rem;
}

.done-figures .done-watch dd {
  font-family: var(--serif);
  font-size: 1.12rem;
  color: var(--bottle);
}

/* The recap: the objectives from folio two, in the past tense of having
   done them, so the card closes against what it opened with. */
.done-recap {
  list-style: none;
  margin: 0 0 0.8rem;
  padding: 0.45rem 0 0;
  max-width: none;
  border-top: 2px solid var(--bottle);
}

.done-recap > li {
  position: relative;
  margin: 0;
  padding: 0.1rem 0 0.1rem 1.3rem;
  font-size: 0.86rem;
  line-height: 1.35;
}

.done-recap > li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.48em;
  width: 0.7rem;
  height: 0.7rem;
  background: var(--brass);
  clip-path: polygon(18% 48%, 8% 60%, 40% 90%, 92% 22%, 80% 12%, 38% 66%);
}

.done-note {
  margin: 0.8rem 0 0;
  max-width: none;
}

.done-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
  margin-top: 0.85rem;
  padding-top: 0.8rem;
  border-top: 2px solid var(--brass);
}

/* ============================================================
   THE STAGE
   At 900 by 640 and up nothing scrolls vertically. Each screen
   becomes a grid of columns, tabs, or sub-steps that fits the
   space the masthead and the pager leave behind.
   ============================================================ */

@media (min-width: 900px) and (min-height: 640px) {

  .js .screen.is-current {
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    gap: var(--gap-v);
    overflow: hidden;
    padding-bottom: 0;
  }

  .screen-head {
    display: grid;
    grid-template-columns: minmax(11rem, 19rem) minmax(0, 1fr);
    gap: 0 var(--gap-h);
    align-items: start;
  }

  .screen-head h2 {
    margin-bottom: 0;
  }

  .screen-head .lead,
  .screen-head .setup {
    margin-bottom: 0;
    padding-top: 1rem;
    max-width: none;
  }

  .screen-body {
    min-height: 0;
    overflow: hidden;
    display: grid;
    gap: var(--gap-h);
    align-items: stretch;
  }

  /* A column is a stack that does not shrink its own contents. The photo is
     the one member allowed to give up height, so a long note or a tall table
     takes the space from the picture and from nothing else. */
  .col {
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
  }

  .col > * {
    flex: 0 0 auto;
  }

  .col > *:last-child {
    margin-bottom: 0;
  }

  .photo {
    flex: 1 1 0;
    min-height: 2.5rem;
    aspect-ratio: auto;
  }

  .tabs {
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    min-height: 0;
  }

  .col > .tabs {
    flex: 1 1 auto;
    min-height: 0;
  }

  /* The :not([hidden]) matters: a bare .tabpanel rule that sets display
     beats the user agent's [hidden] rule on specificity, and every panel
     would stay on the stage at once. */
  .tabpanel:not([hidden]) {
    min-height: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }

  .tabpanel > * {
    flex: 0 0 auto;
  }

  .steps {
    display: grid;
    grid-template-rows: minmax(0, 1fr) auto;
    min-height: 0;
  }

  .steps-body {
    min-height: 0;
    overflow: hidden;
  }

  .step {
    min-height: 0;
  }

  /* ---- screen one: the cover, filling the stage as one board */
  #screen-1.is-current {
    grid-template-rows: minmax(0, 1fr);
  }

  #screen-1 .board {
    min-height: 0;
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr);
    align-content: stretch;
  }

  /* The plate runs the full height of the board, the way a frontispiece is
     tipped in against the board edge. The label stays centred beside it. */
  #screen-1 .board-plate {
    align-self: stretch;
    min-height: 0;
  }

  /* ---- screen two: objectives, why it matters, how it works.
     Three short columns on a tall stage, so each one opens at the top and
     closes at the bottom rather than leaving a third of the page ruled and
     empty underneath it. */
  #screen-2 .screen-body {
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 14rem);
  }

  /* The objectives are set as a schedule: ruled off top and bottom, one
     entry per row, the same furniture as the factbox in the rail. The row
     padding is what takes up the height of the stage, so the column ends
     where the page does. */
  #screen-2 .ticks {
    margin-bottom: 0;
    border-top: 2px solid var(--bottle);
  }

  #screen-2 .ticks > li {
    margin-bottom: 0;
    padding: clamp(0.3rem, 2.2vh, 1.05rem) 0 clamp(0.3rem, 2.2vh, 1.05rem) 1.5rem;
    border-bottom: 1px solid var(--hair-soft);
    font-size: 1rem;
    line-height: 1.45;
  }

  #screen-2 .ticks > li::before {
    top: calc(clamp(0.3rem, 2.2vh, 1.05rem) + 0.45em);
  }

  #screen-2 .col > h3 ~ h3 {
    margin-top: clamp(1rem, 4.5vh, 2.6rem);
  }

  /* The attention line carries the weight of a lead, because that is the
     job it is doing. */
  #screen-2 .hook {
    font-family: var(--serif);
    font-size: clamp(1.02rem, 1.4vw, 1.2rem);
    line-height: 1.42;
    max-width: none;
  }

  #screen-2 .disclaimer {
    margin-top: clamp(0.9rem, 4vh, 2.2rem);
  }

  /* ---- screen three: the statement, with its notes off to the side */
  #screen-3 .screen-body {
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  }

  #screen-3 .table-wrap {
    margin-bottom: 0;
  }

  /* ---- screen four: the argument, the chart, the aside */
  #screen-4 .screen-body {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr) minmax(0, 13rem);
  }

  /* ---- screen five: levers beside the statement, prompts underneath */
  #screen-5 .screen-body {
    grid-template-rows: auto minmax(0, 1fr);
    gap: var(--gap-v);
  }

  /* Levers, statement, and the two figures as one band. The band is what
     leaves the guided prompts underneath room for a full verdict. */
  #screen-5 .sim {
    grid-template-columns: minmax(0, 1fr) minmax(0, 20rem) minmax(0, 11rem);
    gap: var(--gap-v) var(--gap-h);
  }

  #screen-5 .slider-grid {
    grid-template-columns: 1fr 1fr;
  }

  #screen-5 .prompts {
    min-height: 0;
    padding-top: 0.25rem;
    border-top: 1px solid var(--hair-brass);
  }

  #screen-5 .sim .table-wrap {
    margin-bottom: 0;
  }

  #screen-5 .sim-controls { grid-column: 1; grid-row: 1; }
  #screen-5 .sim-table { grid-column: 2; grid-row: 1; }
  #screen-5 .bigfigs {
    grid-column: 3;
    grid-row: 1;
    grid-template-columns: minmax(0, 1fr);
    margin-top: 0;
    align-content: start;
  }

  /* ---- screen six: one item at a time */
  #screen-6 .screen-body {
    grid-template-columns: minmax(0, 52rem);
    justify-content: center;
  }

  #screen-6 .steps {
    min-height: 0;
  }

  /* One item on a stage of its own, sitting on the optical centre line and
     given the weight of a slide rather than a list row. */
  #screen-6 .screen-body {
    grid-template-columns: minmax(0, 46rem);
  }

  #screen-6 .steps-body {
    display: grid;
    align-content: center;
  }

  #screen-6 .step {
    border-top: 4px double var(--bottle);
    padding-top: 1rem;
  }

  #screen-6 .item {
    font-size: clamp(1.3rem, 2.6vw, 1.75rem);
    margin-bottom: 0.85rem;
  }

  #screen-6 .sort {
    font-size: 0.84rem;
    padding: 0.5rem 0.95rem;
  }

  #screen-6 .sort[aria-pressed="true"] {
    padding: calc(0.5rem - 1px) calc(0.95rem - 1px);
  }

  /* ---- screen seven: three timing gaps as tabs */
  #screen-7 .screen-body {
    grid-template-columns: minmax(0, 1fr) minmax(0, 14rem);
  }

  /* ---- screen eight: the four options, and the verdict beside them */
  #screen-8 .screen-body {
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  }

  /* Four panels of equal weight, filling the stage: the shape of the choice
     is part of the question. */
  #screen-8 .options-grid {
    flex: 1 1 auto;
    min-height: 0;
    grid-template-rows: minmax(0, 1fr) minmax(0, 1fr);
  }

  #screen-8 .choice {
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  #screen-8 .col-verdict {
    border-left: 1px solid var(--hair-brass);
    padding-left: var(--gap-h);
  }

  #screen-8 .feedback:not(:empty) {
    border-left: 0;
    padding-left: 0;
  }

  #screen-8 .feedback.is-right,
  #screen-8 .feedback.is-wrong {
    margin-top: 0;
  }

  /* ---- screen nine: chart, reads, takeaway */
  #screen-9 .screen-body {
    grid-template-columns: minmax(0, 1fr);
  }

  /* The chart alone sits in the middle of the stage. With the table open the
     two share the width, and the chart gives up size rather than height. */
  #screen-9 .wf-panel:not(.is-split) {
    justify-content: center;
  }

  #screen-9 .wf-panel.is-split:not([hidden]) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 24rem);
    gap: var(--gap-h);
    align-items: center;
    align-content: center;
  }

  #screen-7 .tabpanel:not([hidden]) {
    justify-content: center;
  }

  #screen-9 .takeaway-panel:not([hidden]) {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    gap: var(--gap-h);
    align-items: start;
  }

  #screen-9 .takeaway,
  #screen-9 .scorecard {
    max-width: none;
    margin-bottom: 0;
  }

  #screen-9 .restart-row {
    margin-top: var(--gap-v);
  }
}

/* Shorter than the frame this was drawn for. Nothing loses a step, but the
   leading, the row padding and the panel padding all come in so the same
   material still lands on one stage. Set to bite below 680 so the 700px
   embed keeps its air. */
@media (min-width: 900px) and (max-height: 679px) {
  :root {
    --ruling-step: 1.5rem;
  }

  body {
    line-height: 1.5;
  }

  td,
  tbody th {
    padding-top: 0.3rem;
    padding-bottom: 0.3rem;
  }

  .compact td,
  .compact tbody th {
    padding-top: 0.26rem;
    padding-bottom: 0.26rem;
  }

  caption {
    padding-top: 0.4rem;
  }

  .takeaway,
  .scorecard {
    padding: 0.7rem 0.9rem 0.6rem;
  }

  .takeaway-list > li {
    margin-bottom: 0.3rem;
    line-height: 1.42;
  }

  .takeaway-foot {
    margin-top: 0.55rem;
    padding-top: 0.5rem;
  }

  .scorelist > li {
    padding: 0.35rem 0;
  }

  .slider-hint {
    line-height: 1.3;
  }

  .aside {
    margin-top: 0.7rem;
    padding-top: 0.6rem;
  }

  .panel-head {
    margin-bottom: 0.5rem;
    padding-bottom: 0.3rem;
  }

  .slider-grid {
    gap: 0.5rem 1.2rem;
  }

  .slider label {
    line-height: 1.22;
  }

  .slider-hint {
    line-height: 1.25;
  }

  .tabpanel {
    padding-top: 0.4rem;
  }

  .tab {
    padding: 0.32rem 0.7rem;
  }

  .feedback {
    margin-top: 0.3rem;
    line-height: 1.46;
  }

  .feedback .fb-note {
    margin-top: 0.2rem;
  }

  #screen-5 .prompts {
    padding-top: 0.1rem;
  }

  /* The objectives schedule loses its air first: at this height there is
     none to give. */
  #screen-2 .ticks > li {
    padding-top: 0.3rem;
    padding-bottom: 0.3rem;
    font-size: 0.95rem;
    line-height: 1.4;
  }

  #screen-2 .ticks > li::before {
    top: calc(0.3rem + 0.42em);
  }

  #screen-2 .col > h3 ~ h3 {
    margin-top: 1rem;
  }

  #screen-2 .disclaimer {
    margin-top: 0.9rem;
  }

  .waterfall {
    max-height: 32vh;
  }
}

/* Between 900 and 1050 the middle column of screen four has to give the
   argument more measure than the chart, or the paragraphs run long. */
@media (min-width: 900px) and (max-width: 1049px) and (min-height: 640px) {
  #screen-4 .screen-body {
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, 10rem);
    gap: var(--gap-v);
  }

  #screen-4 table {
    min-width: 0;
  }

  #screen-4 .chart {
    max-width: 20rem;
  }

  /* The lever column is narrow here, so the value drops under its label
     rather than fighting it for the line. */
  #screen-5 .slider-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
  }

  #screen-5 .slider output {
    font-size: 1rem;
  }

  #screen-5 .bigfig-value {
    font-size: 1.7rem;
  }
}

/* Wide enough for the simulator to run as a single band: levers, statement,
   and the two figures side by side, which is what leaves the guided prompts
   room for a full verdict underneath. */
@media (min-width: 1050px) and (min-height: 640px) {
  #screen-5 .sim {
    grid-template-columns: minmax(0, 1fr) minmax(0, 21rem) minmax(0, 12.5rem);
  }

  #screen-5 .sim-controls { grid-column: 1; grid-row: 1; }
  #screen-5 .sim-table { grid-column: 2; grid-row: 1; }
  #screen-5 .bigfigs {
    grid-column: 3;
    grid-row: 1;
    grid-template-columns: minmax(0, 1fr);
    margin-top: 0;
    align-content: start;
  }
}

/* A little more air once the frame is genuinely tall. */
@media (min-width: 900px) and (min-height: 780px) {
  :root {
    --ruling-step: 1.66rem;
  }

  .lead {
    font-size: clamp(1.08rem, 1.6vw, 1.28rem);
  }

  body {
    line-height: 1.66;
  }
}

/* ---------------------------------------------- reflow to 320px */

@media (max-width: 26rem) {
  .masthead-inner,
  #module,
  .stage-foot {
    padding-left: 1rem;
    padding-right: 1rem;
  }
  .masthead-inner {
    padding-left: calc(1rem + var(--spine-w));
  }
  .progress {
    flex: 1 1 100%;
  }
  .sort,
  .prompt .btn-solid {
    width: 100%;
  }
  .pager {
    flex: 1 1 100%;
    justify-content: space-between;
  }
  .pager button {
    flex: 1 1 0;
  }
  .slider-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.1rem;
  }
  .steps-move {
    flex-wrap: wrap;
  }
}

/* ---------------------------------------------- motion

   Everything here is transform only. Nothing on this page fades: a fade
   takes text through a stretch of frames where it does not meet its
   contrast ratio, and there is nothing these movements need it for. */

@media (prefers-reduced-motion: no-preference) {
  /* The ruling draws itself across the page from the margin rule. */
  .js .screen.is-current::before {
    animation: ruling-draw 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
  }

  /* The folio turns like the corner of a page. */
  .js .progress-text {
    animation: folio-turn 0.42s cubic-bezier(0.16, 1, 0.3, 1) both;
  }

  /* The seal settles onto the closing entry. */
  #done[open] .seal {
    animation: seal-set 0.42s cubic-bezier(0.16, 1, 0.3, 1) both;
  }

  #done[open] .done-card {
    animation: done-rise 0.34s cubic-bezier(0.16, 1, 0.3, 1) both;
  }
}

@keyframes ruling-draw {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

@keyframes folio-turn {
  from { transform: perspective(320px) rotateX(-74deg); }
  to { transform: none; }
}

@keyframes seal-set {
  from { transform: scale(1.22) rotate(-7deg); }
  to { transform: none; }
}

@keyframes done-rise {
  from { transform: translateY(12px); }
  to { transform: none; }
}

/* ---------------------------------------------- reduced motion */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------------------------------------------- print, for the job aid */

@media print {
  html,
  body,
  .frame,
  #module {
    height: auto;
    overflow: visible;
    display: block;
  }
  #module::before,
  .screen::before {
    display: none;
  }
  .stage-foot,
  .masthead .progress,
  .tabstrip,
  .steps-nav {
    display: none;
  }
  .js .screen,
  .js .screen.is-current {
    display: block;
    overflow: visible;
  }
  .js .nojs-h {
    display: block;
  }
  [hidden] {
    display: block !important;
  }
}
