/* ==========================================================================
   Z-READ  ·  stephenmcinerney.com
   One long torn till roll running down a black counter.
   The 1440px artboard is the reference; everything below reflows from it.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */
:root {
  --ink: #221D18;
  --paper: #F3EFE4;
  --counter: #16120E;
  --red: #C2261C;
  --red-deep: #9E1C13;
  --red-pink: #8F170E;
  --greenbar: rgba(200, 215, 190, 0.42);
  --yellow: #EBD8A0;
  --pink: #E5B3A8;
  --crease: #C9C2B2;

  --ink-82: rgba(34, 29, 24, 0.82);
  --ink-80: rgba(34, 29, 24, 0.80);
  --ink-78: rgba(34, 29, 24, 0.78);
  --ink-72: rgba(34, 29, 24, 0.72);
  --ink-68: rgba(34, 29, 24, 0.68);
  --ink-66: rgba(34, 29, 24, 0.66);
  --ink-55: rgba(34, 29, 24, 0.55);
  --ink-45: rgba(34, 29, 24, 0.45);
  --ink-42: rgba(34, 29, 24, 0.42);
  --ink-40: rgba(34, 29, 24, 0.40);
  --ink-30: rgba(34, 29, 24, 0.30);
  --ink-20: rgba(34, 29, 24, 0.20);

  --mono: "IBM Plex Mono", ui-monospace, Menlo, monospace;
  --display: "Big Shoulders Display", "Arial Narrow", sans-serif;
  --wide: "Martian Mono", "IBM Plex Mono", monospace;

  /* the roll: full bleed less a counter margin, capped at its 1320px measure */
  --roll: 1320px;
  --gutter: clamp(8px, 2.5vw, 60px);   /* bare counter down both sides       */
  --pad: clamp(16px, 5vw, 68px);       /* print margin inside the roll       */
  --sprocket: 34px;                    /* punched sprocket margin            */
  --counter-line: repeating-linear-gradient(90deg, rgba(255,255,255,0.018) 0 1px, rgba(0,0,0,0) 1px 3px);
}

/* --------------------------------------------------------------------------
   2. BASE
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--counter);
  color: var(--ink);
  font-family: var(--mono);
  display: flex;
  flex-direction: column;
  align-items: center;
}

h1, h2, h3, h4, p { margin: 0; }

a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
a:hover { color: var(--red-deep); }
.pinkply a:hover { color: var(--red-pink); }
a:focus-visible { outline: 3px solid var(--red); outline-offset: 3px; }
::selection { background: var(--red); color: var(--paper); }

svg { display: block; }

/* --------------------------------------------------------------------------
   3. COUNTER, SHEET, TORN EDGES
   -------------------------------------------------------------------------- */
.counter-top {
  width: 100%;
  height: 44px;
  flex: none;
  background: var(--counter);
  background-image: var(--counter-line);
}

.sheet {
  width: 100%;
  padding: 0 var(--gutter);
  display: flex;
  flex-direction: column;
  align-items: center;
  overflow-x: clip;
}

.tear,
.roll { width: 100%; max-width: var(--roll); }

.tear {
  height: 14px;
  flex: none;
  clip-path: polygon(0 14px, 0 4px, 22px 8.7px, 40px 6.5px, 55px 11.9px, 79px 10px, 104px 3.4px, 129px 4px, 138px 1.6px, 160px 2.2px, 176px 11.2px, 186px 6.1px, 208px 8px, 218px 11.5px, 244px 6.7px, 256px 8.3px, 276px 1.7px, 287px 2.8px, 296px 6.3px, 322px 9.1px, 343px 6.6px, 357px 8.5px, 381px 10.6px, 397px 2.3px, 412px 3.7px, 423px 2.8px, 447px 7.4px, 468px 3.6px, 481px 10.8px, 503px 4.6px, 526px 6.8px, 545px 11.9px, 566px 4.3px, 577px 3.2px, 601px 1.5px, 612px 7.3px, 637px 3.8px, 656px 7.3px, 668px 3.4px, 682px 8.1px, 701px 5.1px, 719px 4.1px, 733px 2.2px, 747px 9.7px, 767px 3.2px, 777px 8.6px, 793px 5.8px, 807px 11.6px, 816px 10.8px, 840px 6.8px, 856px 11.3px, 872px 3.2px, 883px 6.1px, 905px 9.6px, 929px 2.1px, 947px 2px, 964px 8.4px, 974px 5.9px, 988px 5.6px, 1007px 8.3px, 1020px 11.8px, 1044px 2px, 1057px 11.6px, 1082px 11.1px, 1106px 1.8px, 1121px 10.9px, 1141px 9.8px, 1161px 7.8px, 1183px 6.6px, 1207px 4.7px, 1233px 7.7px, 1246px 9.6px, 1255px 5.5px, 1268px 11.5px, 1277px 4.3px, 1296px 8.3px, 1318px 4.2px, 1320px 9.4px, 1320px 14px);
}
.tear--top { background: var(--paper); }
.tear--bottom { background: var(--pink); transform: scaleY(-1); }

.roll {
  position: relative;
  isolation: isolate;
  background: var(--paper);
  color: var(--ink);
  overflow-x: clip;
}

/* --- paper grain + edge shade: two plies of stock, multiplied like real ink --- */
.paper::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 3;
  mix-blend-mode: multiply;
  background-image:
    repeating-linear-gradient(0.5deg, rgba(34,29,24,0.024) 0 1px, rgba(34,29,24,0) 1px 3px),
    repeating-linear-gradient(89.5deg, rgba(34,29,24,0.017) 0 1px, rgba(34,29,24,0) 1px 4px),
    linear-gradient(90deg, rgba(34,29,24,0.060) 0%, rgba(34,29,24,0) 7%, rgba(34,29,24,0) 93%, rgba(34,29,24,0.060) 100%),
    radial-gradient(1500px 1100px at 50% 0%, rgba(34,29,24,0) 40%, rgba(34,29,24,0.042) 100%);
}

/* sprocket margins: 7px holes, 48px pitch, punched through to the counter */
.sprocket {
  position: absolute;
  top: 0;
  bottom: 0;
  width: var(--sprocket);
  z-index: 4;
  pointer-events: none;
  background-image: radial-gradient(circle at calc(var(--sprocket) / 2) 24px, var(--counter) 0 3.5px, rgba(34,29,24,0.32) 3.5px 4.7px, rgba(0,0,0,0) 4.8px);
  background-size: var(--sprocket) 48px;
  background-repeat: repeat-y;
}
.sprocket--left { left: 0; border-right: 1px dashed var(--ink-20); }
.sprocket--right { right: 0; border-left: 1px dashed var(--ink-20); }

/* --------------------------------------------------------------------------
   4. PAGES AND PAGE FURNITURE
   -------------------------------------------------------------------------- */
.page {
  position: relative;
  display: flex;
  flex-direction: column;
}

.page--one {
  gap: clamp(30px, 3.2vw, 46px);
  padding: clamp(26px, 2.7vw, 38px) var(--pad) clamp(58px, 8.2vw, 118px);
}
.page--two {
  gap: clamp(34px, 3.7vw, 52px);
  padding: clamp(34px, 3.8vw, 54px) var(--pad) clamp(40px, 4.5vw, 64px);
}
.page--three {
  gap: clamp(20px, 1.9vw, 26px);
  padding: clamp(34px, 3.8vw, 54px) var(--pad) clamp(32px, 3.2vw, 46px);
}
.page--subtotal {
  gap: clamp(16px, 1.6vw, 22px);
  padding: clamp(26px, 2.4vw, 34px) var(--pad) clamp(32px, 3.2vw, 46px);
}
.page--four {
  gap: clamp(30px, 3.2vw, 46px);
  padding: clamp(32px, 3.5vw, 50px) var(--pad) clamp(56px, 7vw, 100px);
}

/* the page marker, printed up the margin of the roll */
.pagemark {
  position: absolute;
  left: calc(var(--sprocket) + 8px);
  top: 42px;
  z-index: 6;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.30em;
  color: var(--ink-68);
  white-space: nowrap;
}
.page--two .pagemark,
.page--three .pagemark { top: 58px; }
.page--four .pagemark { top: 54px; }

/* fold crease */
.crease {
  position: relative;
  width: 100%;
  height: 3px;
  background: linear-gradient(180deg, rgba(34,29,24,0.05), var(--crease) 40%, var(--crease) 64%, rgba(255,255,255,0.6));
  box-shadow: 0 2px 5px -2px rgba(34,29,24,0.16), 0 -2px 5px -2px rgba(34,29,24,0.07);
}
.crease__label {
  position: absolute;
  right: clamp(12px, 2.8vw, 40px);
  top: -16px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.24em;
  color: var(--ink-66);
}

/* perforation */
.perf {
  position: relative;
  height: 46px;
  flex: none;
  display: flex;
  align-items: center;
  padding: 0 var(--pad);
}
.perf__rule {
  flex: 1;
  height: 0;
  border-top: 2px dashed rgba(34,29,24,0.7);
}
.perf__label {
  padding: 0 14px;
  font-size: 12px;
  letter-spacing: 0.28em;
  color: var(--ink-66);
}
.perf__scissors { flex: none; }

/* --------------------------------------------------------------------------
   5. RULES AND SECTION HEADS
   -------------------------------------------------------------------------- */
.rule { height: 0; }
.rule--heavy { border-top: 2px dashed var(--ink-55); }
.rule--dashed { border-top: 2px dashed var(--ink-45); }
.rule--solid { border-top: 2px solid rgba(34,29,24,0.65); }

.sect-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
}
.sect-head__title {
  min-width: 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: 21px;
  letter-spacing: 0.30em;
  text-shadow: 0.6px 0.4px 0 rgba(194,38,28,0.18);
}
.sect-head__rule {
  flex: 1 1 40px;
  min-width: 40px;
  height: 0;
  border-top: 2px dashed var(--ink-45);
}
.sect-head__note {
  min-width: 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.22em;
  color: var(--ink-66);
}
.sect-head__count {
  flex: none;
  font-weight: 700;
  font-size: 15px;
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   6. DOTTED LEADER ROWS  ·  the signature of a receipt
   -------------------------------------------------------------------------- */
.leader {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  font-family: var(--mono);
  font-size: 15px;
}
.leader__mark {
  flex: none;
  color: var(--red);
}
.leader__label {
  min-width: 0;
  letter-spacing: 0.02em;
  overflow-wrap: break-word;
}
.leader__label b { font-weight: 700; }
.leader__dots {
  flex: 1 1 24px;
  min-width: 20px;
  align-self: flex-end;
  border-bottom: 2px dotted var(--ink-45);
  transform: translateY(-6px);
}
.leader__value {
  flex: none;
  font-weight: 700;
}
.leader__value--num { font-variant-numeric: tabular-nums; }
.leader__value--red { color: var(--red); }
.modifiers--under .leader__value--red { color: var(--red-deep); }
/* the decorative marks sit on the same greenbar rows as those values, so they
   take the same deeper red rather than disagreeing with the line they open */
.modifiers--under .leader__mark { color: var(--red-deep); }

.leader--mod .leader__dots { border-bottom-color: var(--ink-40); }

/* the stacked form of a leader row, for the widths where the row cannot hold
   its label, its dots and its value on one line. the areas are named here and
   do nothing while the row is a flex line; the queries in section 17 turn the
   row into the grid that uses them, group by group, at measured widths. */
.leader__label { grid-area: label; }
.leader__dots { grid-area: dots; }
.leader__value { grid-area: value; }
.leader--mod .leader__mark { grid-area: mark; }

.leader--muted { color: var(--ink-72); }
.leader--muted .leader__value { font-weight: 400; }
.leader--muted .leader__dots { border-bottom-color: var(--ink-30); }
.leader--indent { padding-left: 22px; }

/* the little dashed sub-head inside the totals */
.subrule {
  display: flex;
  align-items: center;
  gap: 10px;
}
.subrule__label {
  flex: 0 1 auto;
  min-width: 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.22em;
  color: var(--ink-66);
}
.subrule__rule {
  flex: 1 1 30px;
  min-width: 30px;
  height: 0;
  border-top: 2px dashed var(--ink-45);
}

/* --------------------------------------------------------------------------
   7. PAGE 1  ·  MASTHEAD, NAME, TOTALS
   -------------------------------------------------------------------------- */
.intro {
  display: flex;
  flex-direction: column;
  gap: clamp(24px, 2.4vw, 34px);
}
.intro__head {
  display: flex;
  flex-direction: column;
  gap: clamp(22px, 2.1vw, 30px);
}
.intro__name {
  display: flex;
  flex-direction: column;
  gap: clamp(18px, 1.81vw, 26px);
}
.block {
  display: flex;
  flex-direction: column;
  gap: clamp(18px, 1.7vw, 24px);
}

.masthead {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 40px;
}
.masthead__id {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 14px;
  line-height: 1.5;
  letter-spacing: 0.03em;
}
.id-line--strong {
  font-weight: 700;
  letter-spacing: 0.16em;
}
.contact {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  flex: none;
}
.contact__label {
  color: var(--red);
  flex: none;
}
.contact__link {
  display: inline-block;
  padding: 12px 0;
  line-height: 20px;
  letter-spacing: 0.03em;
  overflow-wrap: break-word;
}

.masthead__status {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 22px;
  padding-top: 2px;
}
.printing {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.24em;
  color: var(--ink-66);
}
.printing__lamp {
  width: 6px;
  height: 6px;
  flex: none;
  background: var(--red);
  border-radius: 50%;
}

/* the name, double-width printer mode */
.name {
  font-family: var(--wide);
  font-weight: 700;
  font-size: clamp(38px, 12.92vw, 186px);
  line-height: 0.92;
  letter-spacing: -0.014em;
  text-wrap: balance;
  text-shadow: 0.9px 0.6px 0 rgba(194,38,28,0.20);
}

.tagline {
  font-size: clamp(15px, 1.39vw, 20px);
  line-height: 1.5;
  letter-spacing: 0.005em;
}

/* running total */
.totals {
  position: relative;
  display: grid;
  /* two columns exactly while a leader row still fits its label, dots and
     value on one line; one column the moment it does not. the widest row,
     the indented BROWSERS one, measures 446px set that way, so the track is
     floored at 450. the min() keeps it from outrunning a narrow roll. */
  grid-template-columns: repeat(auto-fit, minmax(min(450px, 100%), 1fr));
  gap: clamp(26px, 3.9vw, 56px);
}
.totals__col {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* --------------------------------------------------------------------------
   8. RUBBER STAMPS
   -------------------------------------------------------------------------- */
.stamp {
  display: inline-block;
  border: 3px solid var(--red);
  color: var(--red);
  font-family: var(--display);
  font-weight: 700;
  line-height: 1;
  opacity: 0.82;
  filter: blur(0.25px);
}
.stamp--built {
  border-right-color: rgba(194,38,28,0.16);
  font-size: clamp(20px, 2.09vw, 30px);
  letter-spacing: 0.16em;
  padding: 12px 20px 9px;
  transform: rotate(-3.5deg);
}
.stamp--seven {
  position: absolute;
  left: 50%;
  bottom: -54px;
  border-top-color: rgba(194,38,28,0.14);
  font-size: clamp(19px, 1.74vw, 25px);
  letter-spacing: 0.13em;
  padding: 11px 18px 8px;
  transform: translateX(-50%) rotate(1.8deg);
  white-space: nowrap;
}
.stamp--tests {
  flex: none;
  border-left-color: rgba(194,38,28,0.15);
  font-size: clamp(19px, 1.88vw, 27px);
  letter-spacing: 0.13em;
  padding: 12px 18px 9px;
  transform: rotate(-2.6deg);
  white-space: nowrap;
}
.stamp--offline {
  flex: none;
  border-bottom-color: rgba(194,38,28,0.15);
  font-size: clamp(19px, 1.88vw, 27px);
  line-height: 1.06;
  letter-spacing: 0.12em;
  padding: 14px 18px 11px;
  transform: rotate(-3.2deg);
  text-align: center;
}

/* --------------------------------------------------------------------------
   9. PAGE 2  ·  TEST BLOCK AND WORK TO ORDER
   -------------------------------------------------------------------------- */
.block--tests { gap: clamp(22px, 2vw, 28px); }
.block--testblock { gap: clamp(20px, 1.81vw, 26px); }
.block--order { gap: clamp(22px, 2vw, 28px); }

/* 4,000 automated tests: 100 across, 40 down, no fudging. count them. */
.testblock {
  position: relative;
  width: min(1100px, 100%);
  aspect-ratio: 1100 / 360;
  flex: none;
}
.testblock::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(90deg, #221D18 0 0.2727%, rgba(0,0,0,0) 0.2727% 1%);
  -webkit-mask-image: repeating-linear-gradient(180deg, #000 0 1.6667%, rgba(0,0,0,0) 1.6667% 2.5%);
  mask-image: repeating-linear-gradient(180deg, #000 0 1.6667%, rgba(0,0,0,0) 1.6667% 2.5%);
}
.testblock::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  mix-blend-mode: screen;
  background-image: repeating-linear-gradient(90deg, rgba(243,239,228,0) 0 5.545%, rgba(243,239,228,0.16) 5.545% 6.818%, rgba(243,239,228,0) 6.818% 15.273%);
}

.testnote {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: clamp(24px, 3.9vw, 56px);
}
.testnote__copy { max-width: 660px; }

.prose {
  font-family: var(--mono);
  font-size: 15px;
  line-height: 1.65;
  text-wrap: pretty;
  overflow-wrap: break-word;
  /* running copy is set to a reading measure: 660px, the same width the
     artboard gives the test note, 73 characters at 15px mono. the blocks the
     artboard measures itself keep their own width, set after this rule. */
  max-width: 660px;
}
.prose--lead {
  max-width: 1010px;
  font-size: 17px;
  line-height: 1.6;
}

/* three columns of what gets built to order.
   one column or three, never two: three cards cannot leave one alone on a
   last row if the count divides the items exactly. the switch is measured,
   not rounded: at a 223.8px column the longest card title, SITES, AND THE
   APPS THAT GO WITH THEM, still sets in the two lines the artboard gives it,
   and the roll hands a third of its width to a column at 851px. */
.trio {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(24px, 3.06vw, 44px);
}
@media (min-width: 851px) {
  .trio { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-top: 16px;
  border-top: 3px solid var(--ink);
}
.card__kicker {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.22em;
  color: var(--red);
}
.card__title {
  font-family: var(--display);
  font-weight: 700;
  font-size: 32px;
  line-height: 1;
  min-height: 64px;
  letter-spacing: 0.02em;
  text-shadow: 0.6px 0.4px 0 rgba(194,38,28,0.18);
  text-wrap: balance;
}

/* modifier lists */
.modifiers {
  display: flex;
  flex-direction: column;
  gap: 11px;
}
.modifiers--inset { padding: 0 8px 0 clamp(18px, 4.73vw, 68px); }
.modifiers--under {
  padding: 14px 8px 16px clamp(18px, 4.45vw, 64px);
  background: var(--greenbar);
  border-bottom: 1px dotted var(--ink-42);
}
.modifiers__foot {
  padding-top: 6px;
  font-size: 15px;
  letter-spacing: 0.05em;
  color: var(--ink-80);
}

/* --------------------------------------------------------------------------
   10. LINE ITEMS
   -------------------------------------------------------------------------- */
.group {
  display: flex;
  flex-direction: column;
}

/* category bar: reverse-video, the way a till prints a department head */
.cat-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 16px;
  min-height: 32px;
  flex: none;
  padding: 0 12px;
  background: var(--ink);
  color: var(--paper);
}
.cat-bar__name {
  font-family: var(--display);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 0.26em;
}
.cat-bar__count {
  font-size: 12px;
  letter-spacing: 0.20em;
}

.item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  padding: 0 8px;
  transition: transform 90ms ease-out;
}
.item--tall { min-height: 122px; }
.item--mid { min-height: 88px; }
.item--short { min-height: 78px; }
.item--thin { min-height: 52px; }
.item--bar { background: var(--greenbar); }
.item--ruled { border-bottom: 1px dotted var(--ink-42); }

.item:hover { transform: translateX(3px); }
.item::after {
  content: "";
  position: absolute;
  inset: 0;
  background: #C8D7BE;
  opacity: 0;
  mix-blend-mode: multiply;
  pointer-events: none;
  transition: opacity 90ms ease-out;
}
.item:hover::after { opacity: 0.18; }

.item__no {
  width: 56px;
  flex: none;
  font-weight: 700;
  font-size: 15px;
  color: var(--red);
  font-variant-numeric: tabular-nums;
}
.item__id {
  flex: 0 1 344px;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.item__name {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: 0.01em;
  text-shadow: 0.6px 0.4px 0 rgba(194,38,28,0.18);
  overflow-wrap: break-word;
}
.item__name--xl { font-size: clamp(38px, 3.62vw, 52px); line-height: 0.9; }
.item__name--lg { font-size: clamp(34px, 3.06vw, 44px); line-height: 0.92; }
.item__name--md { font-size: clamp(28px, 2.37vw, 34px); line-height: 0.95; }
.item__name--sm { font-size: clamp(25px, 1.95vw, 28px); line-height: 0.95; }
.item__name--xs {
  flex: 0 1 300px;
  min-width: 0;
  font-size: 25px;
  line-height: 1;
  letter-spacing: 0.02em;
  text-shadow: none;
}
/* the name box gives way while the row is tight, so the description beside it
   is not squeezed into five lines on a tablet. once the row can hold the
   artboard's 300px name box and still set the description in two lines, which
   it can from 1106px up, the box is pinned to its printed measure and the
   1440px line matches the artboard exactly: name 300px, description 640px. */
@media (min-width: 1106px) {
  .item__name--xs { flex: none; width: 300px; }
}
.item__link {
  display: inline-block;
  align-self: flex-start;
  padding: 13px 0;
  font-size: 14px;
  line-height: 18px;
  letter-spacing: 0.06em;
}
.item__desc {
  flex: 0 1 492px;
  min-width: 0;
  font-size: 15px;
  line-height: 1.55;
  text-wrap: pretty;
  overflow-wrap: break-word;
}
.item__desc--tight { line-height: 1.5; }
.item__desc--flex { flex: 1 1 auto; line-height: 1.4; }
.item__chips {
  flex: 0 1 152px;
  /* the widest chip token, [LLM VISION], measures 104.16px set in IBM Plex
     Mono 14px/0.02em, so the column is floored just clear of it */
  min-width: 106px;
  font-size: 14px;
  line-height: 1.7;
  letter-spacing: 0.02em;
  color: var(--ink-78);
}
.chip { display: inline-block; white-space: nowrap; }
.item__status {
  flex: 0 1 92px;
  min-width: 92px;
  text-align: right;
  font-weight: 700;
  font-size: 15px;
  line-height: 1.4;
}
.item__status--red { color: var(--red); }
/* on the greenbar rows the grain overlay takes #C2261C to the edge of 4.5:1,
   so those three uses print in the deeper red the SEEN stamp already uses.
   every other #C2261C sits on paper or the yellow ply and is left alone. */
.item--bar .item__no,
.item--bar .item__status--red { color: var(--red-deep); }
.item__status--num { font-variant-numeric: tabular-nums; }
.item__url {
  width: 148px;
  flex: none;
  display: inline-block;
  padding: 12px 0;
  text-align: right;
  font-weight: 700;
  font-size: 15px;
  line-height: 20px;
  overflow-wrap: break-word;
}

.seen {
  position: absolute;
  /* 274px of the artboard's 1184px line, kept proportional so the stamp
     lands clear of the description column as the row is squeezed */
  right: 23.14%;
  top: 16px;
  border: 2px solid var(--red-deep);
  color: var(--red-deep);
  font-family: var(--display);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.14em;
  padding: 4px 8px 2px;
  transform: rotate(4deg);
  opacity: 0;
  transition: opacity 150ms ease-out;
}
.seen--mid { top: 12px; }
.seen--short { top: 9px; }
.item:hover .seen { opacity: 1; }

/* ORVO, in plain english */
.block--orvo { gap: clamp(14px, 1.3vw, 18px); }
.block--orvo-detail { gap: clamp(16px, 1.5vw, 20px); }
.block--orvo-mods { gap: clamp(22px, 2.1vw, 30px); }

.plain {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 12px;
  padding: 0 8px;
}
.plain__kicker {
  flex: 0 1 auto;
  min-width: 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.22em;
  color: var(--red);
}
.plain .prose { flex: 1 1 320px; line-height: 1.6; }

/* --------------------------------------------------------------------------
   11. THE DOCKET AND THE PREP RAIL
   -------------------------------------------------------------------------- */
.panels {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
  align-items: stretch;
}
.panel {
  display: flex;
  flex-direction: column;
  border: 2px solid var(--ink);
  background: rgba(255,255,255,0.34);
}
.panel__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 16px;
  min-height: 32px;
  flex: none;
  padding: 0 12px;
  background: var(--ink);
  color: var(--paper);
}
.panel__title {
  font-family: var(--display);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 0.26em;
}
.panel__note {
  font-size: 12px;
  letter-spacing: 0.20em;
}
.panel__body {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 18px 18px 16px;
}
.panel__body--rail {
  flex: 1;
  justify-content: space-between;
}
.panel__foot {
  font-size: 14px;
  line-height: 1.5;
  letter-spacing: 0.02em;
  color: var(--ink-82);
}

.docket-line {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.docket-line__head {
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.docket-line__mark {
  width: 22px;
  flex: none;
  font-weight: 700;
  font-size: 16px;
  color: var(--red-deep);
}
.docket-line__name {
  min-width: 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: 27px;
  line-height: 1;
  letter-spacing: 0.05em;
}
.docket-mods {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-left: 32px;
}
.docket-mod {
  font-size: 14px;
  line-height: 1.3;
  letter-spacing: 0.04em;
  color: var(--ink-82);
}

.callout {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border: 2px solid var(--ink);
}
.callout--red { border-color: var(--red-deep); }
.callout__icon { flex: none; }
.callout__text {
  min-width: 0;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.1em;
}
.callout--red .callout__text { color: var(--red-deep); }

.rail {
  width: 100%;
  height: 26px;
  flex: none;
}
.rail-states {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  align-items: stretch;
}
.state {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 11px 10px;
  border: 2px solid var(--ink);
}
.state--away {
  background: var(--ink);
  color: var(--paper);
}
.state__name {
  font-family: var(--display);
  font-weight: 700;
  font-size: 21px;
  line-height: 1;
  letter-spacing: 0.08em;
}
.state__lines {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.state__lines span { height: 3px; background: rgba(34,29,24,0.62); }
.state__lines span:nth-child(2) { width: 74%; background: var(--ink-40); }
.state__lines span:nth-child(3) { width: 52%; background: var(--ink-40); }
.state--away .state__lines span { background: rgba(243,239,228,0.72); }
.state--away .state__lines span:nth-child(2),
.state--away .state__lines span:nth-child(3) { background: rgba(243,239,228,0.45); }
.state__tag {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--red-deep);
}
.state--away .state__tag { color: inherit; }

/* --------------------------------------------------------------------------
   12. CARBON YELLOW PLY
   -------------------------------------------------------------------------- */
.ply-yellow {
  position: relative;
  width: 100%;
  background: var(--yellow);
  border-top: 3px solid var(--ink);
  border-bottom: 3px solid var(--ink);
}
.ply-yellow__inner {
  display: flex;
  align-items: center;
  gap: clamp(24px, 3.06vw, 44px);
  padding: clamp(28px, 2.8vw, 40px) var(--pad);
}
.unplug {
  flex: none;
  width: 320px;
  max-width: 100%;
  height: auto;
}
.ply-yellow__copy {
  display: flex;
  flex-direction: column;
  gap: 16px;
  flex: 1 1 auto;
  min-width: 0;
}
.headline {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(30px, 4.03vw, 58px);
  line-height: 0.92;
  letter-spacing: 0.01em;
  text-wrap: balance;
  text-shadow: 0.7px 0.5px 0 rgba(194,38,28,0.2);
}
.ply-yellow__prose { max-width: 620px; line-height: 1.6; }
.badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px clamp(14px, 1.81vw, 26px);
  padding-top: 4px;
}
.badge {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border: 2px solid var(--ink);
}
.badge--red { border-color: var(--red-deep); }
.badge__dot {
  width: 8px;
  height: 8px;
  flex: none;
  background: var(--ink);
}
.badge--red .badge__dot { background: var(--red-deep); }
.badge__text {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.18em;
}
.badge--red .badge__text { color: var(--red-deep); }

/* --------------------------------------------------------------------------
   13. PAGE 4  ·  THE REST OF THE SALE
   -------------------------------------------------------------------------- */
.block--rest { gap: clamp(24px, 2.4vw, 34px); }
.block--nosale { gap: clamp(20px, 1.81vw, 26px); }
.block--boxes { gap: clamp(22px, 2.1vw, 30px); }

/* one column or three, never two, for the same reason as the trio. these
   three are leader rows, so the measure is the row itself: at a 279px column
   each one still holds its label, a real run of dots and its value on one
   line, which the roll reaches at 1061px. */
.grid-three {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(20px, 3.06vw, 44px);
}
@media (min-width: 1061px) {
  .grid-three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* four cards: one, two or four columns, never three, so the last row is
   never a single card. a spec card needs a 244px column before MYSQL, CRON,
   SSH DEPLOYS sets on the one line the artboard gives it; two such columns
   fit the roll at 598px and four at 1234px. */
.quartet {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(20px, 1.95vw, 28px);
}
@media (min-width: 598px) {
  .quartet { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1234px) {
  .quartet { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.spec {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 14px;
  border-top: 2px solid rgba(34,29,24,0.75);
}
.spec__kicker {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.2em;
  color: var(--red);
}
.spec__title {
  font-family: var(--display);
  font-weight: 700;
  font-size: 27px;
  line-height: 1.02;
}
.spec__note {
  font-size: 15px;
  line-height: 1.6;
}

.notice {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 22px 24px;
  border: 2px solid var(--ink-55);
}
.notice__kicker {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.22em;
  color: var(--red);
}

/* --------------------------------------------------------------------------
   14. CARBON PINK PLY  ·  CUSTOMER COPY
   -------------------------------------------------------------------------- */
.ply-pink {
  position: relative;
  width: 100%;
  background: var(--pink);
  border-top: 3px solid var(--ink);
}
.ply-pink__inner {
  display: flex;
  flex-direction: column;
  gap: clamp(28px, 2.8vw, 40px);
  padding: clamp(36px, 3.62vw, 52px) var(--pad) clamp(38px, 3.9vw, 56px);
}
.ply-pink__top {
  display: flex;
  flex-direction: column;
  gap: clamp(22px, 2.1vw, 30px);
}
.copy-head {
  display: flex;
  flex-direction: column;
  gap: clamp(18px, 1.81vw, 26px);
}
.copy-head__row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 20px;
}
.copy-head__title {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.30em;
}
.copy-head__no {
  font-size: 12px;
  letter-spacing: 0.22em;
  color: var(--ink-78);
}
.total {
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.total__kicker {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.30em;
  color: var(--red-pink);
}
.total__link {
  display: inline-block;
  align-self: flex-start;
  max-width: 100%;
  min-height: 44px;
  font-family: var(--wide);
  font-weight: 700;
  font-size: clamp(15px, 3.06vw, 44px);
  line-height: 1.2;
  letter-spacing: -0.02em;
  text-decoration: none;
  border-bottom: 4px solid var(--red);
  padding-bottom: 6px;
  text-shadow: 0.8px 0.5px 0 rgba(194,38,28,0.22);
  overflow-wrap: break-word;
}
.total__note { max-width: 720px; }

.barcode-block {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 8px;
}
.barcode {
  position: relative;
  width: min(596px, 100%);
  height: 92px;
  flex: none;
}
.barcode::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(90deg, #221D18 0px 1px, transparent 1px 4px, #221D18 4px 6px, transparent 6px 9px, #221D18 9px 11px, transparent 11px 13px, #221D18 13px 15px, transparent 15px 18px, #221D18 18px 20px, transparent 20px 21px, #221D18 21px 25px, transparent 25px 27px, #221D18 27px 28px, transparent 28px 30px, #221D18 30px 33px, transparent 33px 34px, #221D18 34px 38px, transparent 38px 40px, #221D18 40px 46px, transparent 46px 49px, #221D18 49px 50px, transparent 50px 51px, #221D18 51px 57px, transparent 57px 59px, #221D18 59px 63px, transparent 63px 65px, #221D18 65px 66px, transparent 66px 68px, #221D18 68px 71px, transparent 71px 72px, #221D18 72px 74px, transparent 74px 78px, #221D18 78px 79px, transparent 79px 83px, #221D18 83px 85px, transparent 85px 89px, #221D18 89px 92px, transparent 92px 93px, #221D18 93px 96px, transparent 96px 97px, #221D18 97px 98px, transparent 98px 101px, #221D18 101px 104px, transparent 104px 107px, #221D18 107px 109px, transparent 109px 113px, #221D18 113px 114px, transparent 114px 115px, #221D18 115px 118px, transparent 118px 119px, #221D18 119px 122px, transparent 122px 125px, #221D18 125px 128px, transparent 128px 129px, #221D18 129px 135px, transparent 135px 138px, #221D18 138px 142px, transparent 142px 144px, #221D18 144px 146px, transparent 146px 149px, #221D18 149px 151px, transparent 151px 155px, #221D18 155px 156px, transparent 156px 157px, #221D18 157px 161px, transparent 161px 165px, #221D18 165px 166px, transparent 166px 170px, #221D18 170px 176px, transparent 176px 179px, #221D18 179px 181px, transparent 181px 182px, #221D18 182px 186px, transparent 186px 190px, #221D18 190px 191px, transparent 191px 194px, #221D18 194px 196px, transparent 196px 200px, #221D18 200px 202px, transparent 202px 203px, #221D18 203px 204px, transparent 204px 207px, #221D18 207px 211px, transparent 211px 214px, #221D18 214px 215px, transparent 215px 218px, #221D18 218px 222px, transparent 222px 223px, #221D18 223px 226px, transparent 226px 229px, #221D18 229px 233px, transparent 233px 236px, #221D18 236px 239px, transparent 239px 243px, #221D18 243px 245px, transparent 245px 247px, #221D18 247px 248px, transparent 248px 251px, #221D18 251px 254px, transparent 254px 257px, #221D18 257px 259px, transparent 259px 262px, #221D18 262px 264px, transparent 264px 268px, #221D18 268px 270px, transparent 270px 273px, #221D18 273px 274px, transparent 274px 277px, #221D18 277px 280px, transparent 280px 282px, #221D18 282px 284px, transparent 284px 286px, #221D18 286px 288px, transparent 288px 291px, #221D18 291px 297px, transparent 297px 300px, #221D18 300px 303px, transparent 303px 306px, #221D18 306px 310px, transparent 310px 312px, #221D18 312px 315px, transparent 315px 318px, #221D18 318px 320px, transparent 320px 321px, #221D18 321px 325px, transparent 325px 329px, #221D18 329px 333px, transparent 333px 335px, #221D18 335px 337px, transparent 337px 341px, #221D18 341px 343px, transparent 343px 347px, #221D18 347px 350px, transparent 350px 354px, #221D18 354px 360px, transparent 360px 363px, #221D18 363px 365px, transparent 365px 368px, #221D18 368px 369px, transparent 369px 371px, #221D18 371px 372px, transparent 372px 374px, #221D18 374px 377px, transparent 377px 380px, #221D18 380px 384px, transparent 384px 388px, #221D18 388px 394px, transparent 394px 397px, #221D18 397px 398px, transparent 398px 401px, #221D18 401px 403px, transparent 403px 404px, #221D18 404px 406px, transparent 406px 410px, #221D18 410px 413px, transparent 413px 414px, #221D18 414px 416px, transparent 416px 418px, #221D18 418px 419px, transparent 419px 421px, #221D18 421px 423px, transparent 423px 425px, #221D18 425px 427px, transparent 427px 431px, #221D18 431px 432px, transparent 432px 435px, #221D18 435px 438px, transparent 438px 440px, #221D18 440px 442px, transparent 442px 443px, #221D18 443px 446px, transparent 446px 449px, #221D18 449px 453px, transparent 453px 455px, #221D18 455px 456px, transparent 456px 458px, #221D18 458px 462px, transparent 462px 465px, #221D18 465px 467px, transparent 467px 471px, #221D18 471px 475px, transparent 475px 478px, #221D18 478px 481px, transparent 481px 483px, #221D18 483px 487px, transparent 487px 490px, #221D18 490px 493px, transparent 493px 496px, #221D18 496px 500px, transparent 500px 502px, #221D18 502px 505px, transparent 505px 507px, #221D18 507px 510px, transparent 510px 514px, #221D18 514px 518px, transparent 518px 521px, #221D18 521px 523px, transparent 523px 526px, #221D18 526px 529px, transparent 529px 530px, #221D18 530px 534px, transparent 534px 537px, #221D18 537px 540px, transparent 540px 543px, #221D18 543px 545px, transparent 545px 546px, #221D18 546px 547px, transparent 547px 551px, #221D18 551px 554px, transparent 554px 558px, #221D18 558px 564px, transparent 564px 565px, #221D18 565px 567px, transparent 567px 570px, #221D18 570px 572px, transparent 572px 575px, #221D18 575px 577px, transparent 577px 581px, #221D18 581px 585px, transparent 585px 586px, #221D18 586px 588px, transparent 588px 591px, transparent 591px 596px);
}
.barcode__label {
  width: min(596px, 100%);
  text-align: center;
  font-size: 12px;
  letter-spacing: 0.4em;
}

.copy-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px 20px;
}
.copy-foot__thanks {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(26px, 2.78vw, 40px);
  line-height: 1;
  letter-spacing: 0.14em;
  text-shadow: 0.6px 0.4px 0 rgba(194,38,28,0.2);
}
.copy-foot__end {
  font-size: 12px;
  letter-spacing: 0.22em;
  color: var(--ink-78);
}

/* --------------------------------------------------------------------------
   15. COUNTER FOOT
   -------------------------------------------------------------------------- */
.counter-foot {
  width: 100%;
  max-width: none;
  flex: none;
  padding: clamp(24px, 2.4vw, 34px) var(--gutter) clamp(28px, 2.8vw, 40px);
  background: var(--counter);
  background-image: var(--counter-line);
  color: rgba(243,239,228,0.62);
  font-size: 12px;
  letter-spacing: 0.2em;
}
/* the band runs the full width of the counter, the way the head does;
   only the printing on it is held to the measure of the roll */
.counter-foot__inner {
  width: 100%;
  max-width: var(--roll);
  margin-inline: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 24px;
}

/* --------------------------------------------------------------------------
   16. THE PRINTER IS STILL RUNNING: one motion idea, three tells
   the sentence is fully set in the markup and never sized by the animation.
   a paper-coloured curtain starts fully retracted (left: 100%) and is only ever
   pulled back across it by the backwards fill, so if the font is late, the
   animation is refused, or the roll is exported flat, the line reads complete.
   -------------------------------------------------------------------------- */
@keyframes zr-type { from { left: 0; } to { left: 100%; } }
@keyframes zr-caret { 0%, 49% { border-left-color: #C2261C; } 50%, 100% { border-left-color: rgba(194,38,28,0); } }
@keyframes zr-lamp { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }

.typed {
  position: relative;
  display: inline-block;
  white-space: nowrap;
}
.typed::after {
  content: "";
  position: absolute;
  top: -4px;
  bottom: -4px;
  left: 100%;
  right: -11px;
  pointer-events: none;
  background: var(--paper);
  border-left: 11px solid var(--red);
  animation: zr-type 1.5s steps(67, end) 0.2s both, zr-caret 1.06s step-end 0.2s infinite;
}
.lamp { animation: zr-lamp 1.4s ease-in-out infinite; }

/* --------------------------------------------------------------------------
   17. REFLOW
   The roll is a narrow vertical column by nature, so it takes the squeeze
   well. The grids are not listed here: each one carries its own breakpoints
   beside its own rule, at the measured width where one of its cards stops
   fitting, and each steps between column counts that divide its item count
   exactly so a card is never left alone on a last row. What gives on a
   viewport, in order: the fixed measure columns, then the sprocket margins,
   then the line items themselves.
   -------------------------------------------------------------------------- */

/* --- 1356px: the ORVO modifier list stacks. its labels are the longest lines
       on the roll, 60 to 90 characters, and the widest of them, the CLOUD POS
       row, needs 1041px of the row before the dots begin. the roll gives that
       row 1081px at 1357px of viewport, so below that the value drops to its
       own leader underneath and the dots keep the width of the row rather
       than collapsing to a stub while the label wraps. --- */
@media (max-width: 1356px) {
  .modifiers--inset .leader {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "label label"
      "dots  value";
    align-items: end;
    row-gap: 2px;
  }
  .modifiers--inset .leader--mod {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
      "mark label label"
      "mark dots  value";
  }
  .modifiers--inset .leader--mod .leader__mark { align-self: start; }
}

/* --- 1180px: the page marker comes off the margin and prints across --- */
@media (max-width: 1180px) {
  .pagemark {
    position: static;
    writing-mode: horizontal-tb;
    transform: none;
    white-space: normal;
    margin-bottom: -6px;
  }
  .page--two .pagemark,
  .page--three .pagemark,
  .page--four .pagemark { top: auto; }
}

/* --- 1132px: the same for the three modifier lines on the greenbar, whose
       longest label needs 864px of the row. it clears that at 1133px. --- */
@media (max-width: 1132px) {
  .modifiers--under .leader {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "label label"
      "dots  value";
    align-items: end;
    row-gap: 2px;
  }
  .modifiers--under .leader--mod {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
      "mark label label"
      "mark dots  value";
  }
  .modifiers--under .leader--mod .leader__mark { align-self: start; }
}

/* --- 1000px: the sprocket margin narrows --- */
@media (max-width: 1000px) {
  :root { --sprocket: 22px; }
  .card__title { min-height: 0; }
  .testnote { flex-direction: column; align-items: flex-start; }
}

/* --- 988px: and the same for the three TO ORDER lines. these run the full
       width of the roll with nothing indenting them, so they are the last of
       the three lists to give way: they still fit at 989px. --- */
@media (max-width: 988px) {
  .block--order .modifiers .leader {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "label label"
      "dots  value";
    align-items: end;
    row-gap: 2px;
  }
  .block--order .modifiers .leader--mod {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
      "mark label label"
      "mark dots  value";
  }
  .block--order .modifiers .leader--mod .leader__mark { align-self: start; }
}

/* --- 860px: the docket and the rail stack, the line items break up --- */
@media (max-width: 860px) {
  :root { --sprocket: 0px; }
  .sprocket { display: none; }

  .panels { grid-template-columns: minmax(0, 1fr); }
  .ply-yellow__inner { flex-direction: column; align-items: flex-start; }
  .unplug { flex: none; }
  .stamp--offline { align-self: flex-start; }

  /* line items: number and name up top, then the description, the chips
     and the status, each on its own line, the way a narrow till prints */
  .item {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr);
    grid-template-areas:
      "no   id"
      "desc desc"
      "chips chips"
      "status status";
    align-items: start;
    gap: 6px 8px;
    padding: 16px 8px;
    min-height: 0;
  }
  .item__no { grid-area: no; width: auto; }
  .item__id { grid-area: id; }
  .item__desc { grid-area: desc; }
  .item__chips { grid-area: chips; }
  .item__status { grid-area: status; text-align: left; }
  .item__url { grid-area: status; text-align: left; width: auto; }
  .item__name--xs { width: auto; grid-area: id; }
  .item--sundry {
    grid-template-areas:
      "no   id"
      "desc desc"
      "status status";
  }
  .seen, .seen--mid, .seen--short {
    right: 8px;
    top: 10px;
  }

  /* --- THE REPRINT. The roll stops being a wide sheet well before a phone,
         so anything that is receipt furniture rather than fact comes off the
         paper from here down -- a landscape phone, a split-screen window and
         a small tablet get the short print too, not just the 560px phone.
         Measured: without this the 561-860px band ran 9,527px against the
         phone's 6,710px, a 42% jump across a single pixel. Spacing and type
         sizes are deliberately NOT touched here; those stay in the 560 block. */

  /* receipt-isms, not facts. the solo line is printed in full in NOT ON THIS
     DOCKET further down the roll, so nothing true is lost. */
  .id-line--meta { display: none; }

  /* furniture for a four-page docket; the narrow roll is one scroll, and the
     marker costs a whole line of it four times over. */
  .pagemark { display: none; }

  /* the ORVO modifiers print the way a till prints a modifier: the name and
     what it comes to. the paragraph above the list already says what the
     product does. the descriptions stay in the markup for the wide roll. */
  .mod__desc { display: none; }
  .modifiers--inset .leader {
    display: flex;
    align-items: flex-end;
    column-gap: 10px;
    row-gap: 0;
  }

  /* the exception, and it is a real one: the three rows whose value is APP
     STORE are downloadable apps, not parts of the till. "VISION ... APP
     STORE" on its own tells a reader nothing, and ORVO Vision is one of the
     four apps this page counts. So those three keep their description. It
     also hands AUTHENTICATOR the full width of the row, which is what stopped
     it breaking as AUTHENTICATO / R at 320px. */
  .modifiers--inset .leader--app .mod__desc { display: inline; }

  /* a row that is a list of names, or an app with its description, cannot
     hold label, dots and value on one line of this roll -- and a stub of dots
     after a three-line label is not how a receipt looks. */
  .modifiers--inset .leader--names,
  .modifiers--inset .leader--app {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
      "mark label label"
      "mark dots  value";
    align-items: end;
    row-gap: 2px;
  }
  .modifiers--inset .leader--names .leader__mark,
  .modifiers--inset .leader--app .leader__mark { align-self: start; }

  /* --- the body face. below this width the roll is narrow enough that 15px
         mono runs the copy to three times the lines it takes on the wide
         sheet. same words, set at the 14px floor with a tighter leading, so
         a landscape phone and a small tablet get the short print too rather
         than only the 560px phone. Nothing drops below the floor and the
         typeface does not change. --- */
  .prose { font-size: 14px; line-height: 1.45; }
  .prose--lead { font-size: 15px; line-height: 1.45; }
  .leader { font-size: 14px; }
  .item__desc { font-size: 14px; line-height: 1.42; }
  .item__desc--tight { line-height: 1.42; }
  .item__desc--flex { line-height: 1.4; }
  .item__status, .item__url { font-size: 14px; }
  .spec__note { font-size: 14px; line-height: 1.4; }
  .panel__foot { font-size: 14px; line-height: 1.4; letter-spacing: 0.01em; }
  .modifiers__foot { font-size: 14px; letter-spacing: 0.02em; padding-top: 3px; }
  .card__title { font-size: 26px; }
  .spec__title { font-size: 22px; }
  .state__name { font-size: 16px; }
}

/* --- 760px: stamps stop being nailed to the layout --- */
@media (max-width: 760px) {
  .stamp--seven {
    position: static;
    align-self: center;
    margin-top: 16px;
    transform: rotate(1.8deg);
    white-space: normal;
    text-align: center;
  }
  .stamp--tests { white-space: normal; }
  .masthead { flex-direction: column; gap: 26px; }
  .masthead__status { align-items: flex-start; }
}

/* --- 720px: the printed sentence no longer fits one line of the roll, so the
       curtain and its caret come off and the line is simply printed --- */
@media (max-width: 720px) {
  .typed { white-space: normal; }
  .typed::after { display: none; }
}

/* --- 700px: the printed heads and the boxes are set smaller --- */
@media (max-width: 700px) {
  .sect-head__title { font-size: 18px; letter-spacing: 0.2em; }
  .cat-bar, .panel__head { padding: 5px 12px; }
  .cat-bar__name { font-size: 17px; letter-spacing: 0.2em; }
  .panel__title { font-size: 17px; letter-spacing: 0.2em; }
  .prose--lead { font-size: 16px; }
  .notice { padding: 18px 16px; }
  .panel__body { padding: 16px 14px 14px; }
  .docket-mods { padding-left: 24px; }
}

/* --- 620px: a section head and a sub-head no longer fit across the roll,
       so each drops its tail onto the line under it --- */
@media (max-width: 620px) {
  .sect-head { row-gap: 4px; }
  .sect-head__note { flex: 1 1 auto; min-width: 0; }
  .sect-head__count { margin-left: auto; }

  .subrule { flex-wrap: wrap; row-gap: 4px; }
  .subrule__label { flex: 1 1 100%; }
  .subrule__rule { flex: 1 1 100%; min-width: 0; }

  .leader--indent { padding-left: 14px; }
  .state { padding: 9px 7px; }
  .state__name { font-size: 18px; letter-spacing: 0.04em; }
}

/* --- 560px: a line no longer fits its label beside its value, so the value
       drops to its own leader underneath, as a till would. the dots keep the
       whole width of the row rather than collapsing to a stub. --- */
@media (max-width: 560px) {
  .leader {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "label label"
      "dots  value";
    align-items: end;
    row-gap: 2px;
  }
  .leader--mod {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
      "mark label label"
      "mark dots  value";
  }
  .leader--mod .leader__mark { align-self: start; }
}

/* --- 480px: the tightest setting the roll prints at --- */
@media (max-width: 480px) {
  /* column-gap, not gap: the shorthand would write both axes and put the
     stacked row's 2px label-to-dots gap back up to 8px */
  .leader { column-gap: 8px; }
  .modifiers--under { padding-left: 16px; }
  .docket-line__name { font-size: 24px; }
  .callout { padding: 8px 10px; }
  .rail-states { grid-template-columns: minmax(0, 1fr); }
  .callout__text { letter-spacing: 0.06em; }
  .badge__text { letter-spacing: 0.12em; }
  .copy-head__title { letter-spacing: 0.2em; }
}

/* --------------------------------------------------------------------------
   17b. THE 58MM ROLL  ·  the phone
   Below 560px the roll is the width of a real till roll, not a page, and the
   wide-measure setting reads like an essay in a gutter. So it is reprinted
   the way a till prints: every line item keeps every word, the modifier
   lines go back to a name and a value, and everything that was only ever
   furniture on the wide roll comes off the paper. Nothing in this section
   applies above 560px, so the 1440px artboard is untouched.
   -------------------------------------------------------------------------- */
@media (max-width: 560px) {

  /* --- the roll itself. the print margin is set for a 1320px roll; on a
         58mm one it is a tenth of the screen on each side. taking it to 14px
         is still a real margin and buys four characters a line, which is
         enough to bring several section notes and leader rows back onto one
         line rather than two. --- */
  :root { --pad: 14px; --gutter: 8px; }
  .counter-top { height: 18px; }

  /* --- the header. a visitor gets the trade, the name, the town, the
         address to write to, the lamp and the stamp. the docket number, the
         period and the till number are receipt-isms rather than facts, and
         the solo fact is printed in full in NOT ON THIS DOCKET further down
         the roll, so nothing true is lost by not printing them twice. --- */
  .masthead { gap: 18px; }
  .masthead__id { gap: 4px; letter-spacing: 0.015em; }
  .contact { gap: 6px; }
  .contact__link { letter-spacing: 0.015em; }
  .masthead__status { gap: 13px; }
  .stamp--built { padding: 9px 15px 7px; }

  /* --- the page marker is furniture for a four-page docket. the phone roll
         is one scroll, and below 1180px the marker prints across and costs a
         whole line of the roll four times over. --- */

  /* --- the ORVO modifiers print the way a till prints a modifier: the name
         and what it comes to. the paragraph above the list already says what
         the product does and the names carry themselves, so the descriptions
         come off the paper here. they stay in the markup, for the wide roll
         and for anyone reading the source. --- */
  /* the one row that is four names rather than a name and a description
     keeps the stacked form: it cannot hold four names and a value on a line
     of this roll, and a stub of dots after a three-line label is not how a
     receipt looks. */

  /* the subtotal's three rows hold a label, a real run of dots and a value
     on one line of this roll once the body face is set at 14px, so they are
     printed as rows rather than stacked. */
  .grid-three { gap: 10px; }
  .grid-three .leader {
    display: flex;
    align-items: flex-end;
    column-gap: 10px;
    row-gap: 0;
  }

  /* --- the body face. the roll is 38 characters wide here, so the running
         copy is set at the 14px floor with a tighter leading: same words,
         fewer lines. the typeface does not change and nothing drops below
         the floor. mono letter-spacing comes off the two pieces of running
         copy that carry it; headings, labels and stamps keep theirs. --- */
  /* four boxes, two across: two full rows, so no card is left alone on the
     last one, and the block costs a third less of the roll than a column. */
  .quartet { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 11px 13px; }
  .spec { gap: 4px; padding-top: 8px; }
  .notice { gap: 7px; padding: 12px 11px; }

  /* --- vertical rhythm. the roll is set closer down its whole length. --- */
  .page--one      { gap: 18px; padding: 14px var(--pad) 20px; }
  .page--two      { gap: 18px; padding: 18px var(--pad) 20px; }
  .page--three    { gap: 12px; padding: 18px var(--pad) 16px; }
  .page--subtotal { gap: 10px; padding: 14px var(--pad) 16px; }
  .page--four     { gap: 18px; padding: 18px var(--pad) 22px; }

  .intro { gap: 16px; }
  .intro__head { gap: 13px; }
  .intro__name { gap: 11px; }

  .block { gap: 11px; }
  .block--tests, .block--order, .block--orvo-mods, .block--boxes { gap: 13px; }
  .block--testblock { gap: 11px; }
  .block--orvo { gap: 9px; }
  .block--orvo-detail { gap: 10px; }
  .block--rest { gap: 14px; }
  .block--nosale { gap: 12px; }

  .sect-head { row-gap: 3px; }
  .totals { gap: 14px; }
  .totals__col { gap: 6px; }
  .stamp--seven { margin-top: 9px; }
  .modifiers { gap: 6px; }
  .modifiers--under { padding: 9px 8px 10px 14px; }

  .testnote { gap: 12px; }
  .trio { gap: 14px; }
  .card { gap: 6px; padding-top: 10px; }
  .plain { gap: 3px 10px; }

  /* the docket and the rail: two drawn boxes, set closer inside their rules */
  .panels { gap: 13px; }
  .panel__body { gap: 8px; padding: 10px 10px 9px; }
  .docket-line { gap: 4px; }
  .docket-mods { padding-left: 18px; }
  .callout { padding: 7px 9px; }
  .rail { height: 20px; }
  /* the rail above is drawn with three clips on it, so the three states stay
     three across rather than stacking into a column three times the height.
     the name is set down a step to hold ON THE PASS on one line of a 98px
     column; nothing else about the state changes. */
  .rail-states { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 7px; }
  .state { gap: 5px; padding: 7px 6px; }
  .state__lines { gap: 4px; }

  /* --- the line items. the chips and the status share a line rather than
         taking one each: both are short, and a till prints them together at
         the foot of an item. the forced break inside a status is a wide-roll
         break and comes out here. every word of every description stays. --- */
  .item {
    grid-template-columns: 34px minmax(0, 1fr) auto;
    grid-template-areas:
      "no    id    id"
      "desc  desc  desc"
      "chips chips status";
    gap: 4px 8px;
    padding: 9px 6px;
  }
  .item--sundry {
    grid-template-areas:
      "no     id     id"
      "desc   desc   desc"
      "status status status";
  }
  .item__status {
    min-width: 0;
    text-align: right;
    align-self: end;
    overflow-wrap: break-word;
  }
  /* the forced break in a status is a wide-roll break: the phone row has the
     width for LOCAL FIRST on one line. the markup carries a space before the
     break, which the wide roll collapses away at the end of the line. */
  .item__status br { display: none; }
  .item--sundry .item__status, .item__url { text-align: left; }
  /* the name and the address it lives at print on one line, the way a till
     prints an item and its code. the 44px tap target is unchanged: the link
     keeps its padding and the name now sits inside that same line box. */
  .item__id { flex-direction: row; flex-wrap: wrap; align-items: baseline; column-gap: 10px; }
  .item__link { padding: 13px 0; align-self: baseline; }
  .seen, .seen--mid, .seen--short { top: 7px; }

  /* the yellow ply: the drawing is set to the width of the roll */
  .ply-yellow__inner { gap: 12px; padding: 18px var(--pad); }
  .unplug { width: 190px; }
  .ply-yellow__copy { gap: 11px; }
  .badges { gap: 8px 12px; padding-top: 2px; }
  .badge { padding: 8px 11px; }

  .perf { height: 30px; }

  /* the customer copy: the total is the point of it, the rest is set closer */
  .ply-pink__inner { gap: 16px; padding: 22px var(--pad) 24px; }
  .ply-pink__top { gap: 13px; }
  .copy-head { gap: 11px; }
  .total { gap: 10px; }
  .barcode { height: 46px; }
  .barcode-block { gap: 8px; margin-top: 2px; }
  .copy-foot { gap: 8px 16px; }

  .counter-foot { padding: 12px var(--gutter) 16px; }
}

/* --------------------------------------------------------------------------
   18. PRINTER STOPPED: nothing loops, nothing is withheld,
       the line is already printed
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .typed::after { animation: none; left: 100%; border-left-color: rgba(194,38,28,0); }
  .lamp { animation: none; opacity: 1; }
  .item { transition: none; }
  .item:hover { transform: none; }
  .item::after { transition: none; }
  .seen { transition: none; }
}

/* --------------------------------------------------------------------------
   19. PRINT: it is a receipt. let it be one.
   -------------------------------------------------------------------------- */
@media print {
  :root { --gutter: 0px; --pad: 12mm; }
  body { background: #fff; }
  .counter-top, .sprocket, .tear { display: none; }
  .sheet { padding: 0; }
  .typed::after { display: none; }
  .lamp { animation: none; opacity: 1; }
  a { text-decoration: underline; }
}
