/* assets/style.css — the site's layout and type, "The Annotated Machine".
   Every colour comes from tokens.css. This file declares no literal colour.

   Three class names outlived the colour that named them and are now gone: what was
   .band--blueprint is .band--accent, and .s-blue / .f-blue are .s-accent / .f-accent.
   The markup belongs to other tickets, so every rule that matches one of them also matches
   the semantic name the markup will move to — .band--accent, .s-accent, .f-accent — and the
   rename lands without a silent gap in between. Each pair collapses once the markup moves. */

/* ============================================================ 0. reset and ground */

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

html {
  /* two rows stick now — the bar and the six page names under it — so an anchor has to
     clear both. The sub-band is one row of --tap; on a phone it is one row of --s6. */
  scroll-padding-top: calc(var(--header-h) + var(--tap) + var(--hair) * 2);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-text);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  font-weight: var(--w-body);
}

:lang(hy) { font-family: var(--font-hy); line-height: var(--lh-hy); }
/* figures line up where a column of them is read down — tables and the configurators'
   readouts; in a sentence a figure is the text's own, proportional */
table, output { font-variant-numeric: tabular-nums; }

::selection { background: var(--accent-fill); color: var(--on-accent); }
:focus-visible {
  outline: var(--focus) solid var(--accent);
  outline-offset: 2px;
  border-radius: 1px;
}

* { scrollbar-color: var(--line-control) transparent; scrollbar-width: thin; }
*::-webkit-scrollbar { height: var(--scrollbar); width: var(--scrollbar); }
*::-webkit-scrollbar-track { background: var(--grid); }
*::-webkit-scrollbar-thumb { background: var(--line-control); border-radius: 0; }

p { margin: 0 0 var(--s4); }
h1, h2, h3 { margin: 0; text-wrap: balance; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img, svg { max-width: 100%; }
/* a figure takes no margin of its own: the browser's 40px either side pushed every drawing in
   from its column; a component that wants air or centring says so (.plate--figure:has(.rack)) */
figure { margin: 0; }
a { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 0.12em; text-decoration-thickness: 1px; }
a:hover, a:active { color: var(--accent-deep); }

/* ============================================================ 1. typography roles */

.display {
  font-size: var(--t-display);
  line-height: var(--lh-display);
  letter-spacing: var(--tr-display);
  font-weight: var(--w-bold);
  max-width: 20ch;
}
.h2 {
  font-size: var(--t-h2);
  line-height: var(--lh-h2);
  letter-spacing: var(--tr-h2);
  font-weight: var(--w-bold);
  max-width: 22ch;
}
.h3 {
  font-size: var(--t-h3);
  line-height: 1.28;
  letter-spacing: -0.01em;
  font-weight: var(--w-bold);
}
.lead {
  font-size: var(--t-lead);
  line-height: var(--lh-lead);
  max-width: var(--measure);
  color: var(--ink);
}
.body  { max-width: var(--measure); }

.eyebrow, .caption, .chip {
  font-family: var(--font-label);
}
.eyebrow {
  font-size: var(--t-micro);
  font-weight: var(--w-mid);
  letter-spacing: var(--tr-eyebrow);
  text-transform: uppercase;
  color: var(--ink-2);
}
.caption {
  font-size: var(--t-mono);
  letter-spacing: var(--tr-caption);
  color: var(--ink-2);
  margin-top: var(--s3);
  display: block;
}
.chip {
  font-size: var(--t-micro);
  letter-spacing: var(--tr-chip);
  color: var(--ink-2);
  text-transform: uppercase;
}

/* a separator that belongs to the sentence, not to the layout */
.vh {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

/* ============================================================ 2. bands and plates */

/* Two tiers of rhythm, and only two. A chapter band opens and closes with --band-pad (96px,
   56px at 900px and under); a secondary band — the FAQ, the form, a short aside — carries
   .band--minor and --band-pad-dense (64px, 48px). The tier is the class; nothing else in
   this file sets a band's air. */
.band { position: relative; padding: var(--band-pad) 0; }
.band--minor { padding-block: var(--band-pad-dense); }
/* a band that took in its neighbour: the part starts one step lower and opens with the same
   .band__head a band does, so the print rules that keep a head with what follows reach it.
   It stands here, before the .mt-* utilities, so a utility written on a part still wins. */
.band__part { margin-top: var(--s8); }
.band--paper   { background: var(--paper); }
.band--surface { background: var(--surface); border-block: var(--hair) solid var(--line); }
/* the ruling lives inside a drawing (.plate--figure) and nowhere else: a ruled band behind a
   ruled plate read as a grid in a grid. The class stays as the name of the drawing band. */
.band--grid {
  background-color: var(--paper);
  border-block: var(--hair) solid var(--line);
}
.band--machine {
  /* the values are re-pointed in tokens.css §2.5: on this band --ink, --surface and their
     neighbours are the machine set, and a plate, callout or table laid on it names the
     paper set again. Nothing here is painted class by class. */
  background: var(--paper);
  color: var(--ink);
  border-block: var(--hair) solid var(--line);
}
.band--accent {
  /* was a flat blue flood; now apricot drawing paper framed by its own rule, so the
     band reads as a register of the same world rather than a slab of one colour */
  background-color: var(--accent-wash);
  background-image:
    linear-gradient(to right,  var(--accent-grid) 1px, transparent 1px),
    linear-gradient(to bottom, var(--accent-grid) 1px, transparent 1px);
  background-size: 24px 24px;
  border-block: var(--stroke) solid var(--accent);
}

.inner {
  width: 100%;
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 var(--margin);
}

/* the corner marks: FIG. n top-left, subject top-right, revision bottom-right */
.band__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
  padding-bottom: var(--s3);
  border-bottom: var(--hair) solid var(--line);
  margin-bottom: var(--s5);
}
/* The corner mark speaks — mono, capitals, a chip — on the first screen and on the signature
   band. Every other band names its subject in a quiet line of the reading face. */
.band__head .eyebrow {
  font-family: var(--font-text);
  font-size: var(--t-body-2);
  letter-spacing: normal;
  text-transform: none;
}
#signature .band__head .eyebrow {
  font-family: var(--font-label);
  font-size: var(--t-micro);
  letter-spacing: var(--tr-eyebrow);
  text-transform: uppercase;
}
/* the chip keeps the right-hand edge when a long eyebrow pushes it onto its own line */
.band__head > :last-child:not(:first-child) { margin-left: auto; }
.band--accent .band__head { border-bottom-color: var(--accent); }
.band--accent .eyebrow { color: var(--accent-ink); }

.band__title { margin-top: var(--s4); }
.band__title .h2 { margin-bottom: var(--s5); }
/* heading to lead is one step, lead to what it introduces is two, and each gap has this one
   source: no spacing utility stands on these nodes. The lead is held at one class by :where(),
   so a utility would win it by order; what follows a lead keeps the weight that sets it over
   a component's own margin (.legend, .links) */
.h2 + :where(.lead) { margin-top: var(--s5); }
.lead + :is(ul, ol, div, figure) { margin-top: var(--s6); }
.band__title .lead { margin-bottom: 0; }

/* a plate: one drawing, one table, one form — bordered, 4 px, nothing rounder */
.plate {
  position: relative;
  background: var(--surface);
  border: var(--hair) solid var(--line);
  border-radius: var(--radius);
  padding: var(--s6);
}
.plate--figure {
  background-color: var(--surface);
  background-image:
    linear-gradient(to right,  var(--grid) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid) 1px, transparent 1px);
  background-size: 16px 16px;
}
.plate--figure { padding: var(--s4); }
.plate__mark {
  position: absolute;
  font-family: var(--font-label);
  font-size: var(--t-micro);
  letter-spacing: var(--tr-chip);
  text-transform: uppercase;
  color: var(--ink-2);
  background: var(--surface);
  padding: 0 var(--s1);
}
.plate__mark--tl { top: -7px; left: var(--s4); }
.plate__mark--tr { top: -7px; right: var(--s4); }
.plate__mark--br { bottom: -7px; right: var(--s4); }

/* ============================================================ 3. grid lanes */

.cols {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gutter);
  align-items: start;
}
.c-7 { grid-column: span 7; }
.c-5 { grid-column: span 5; }
.c-6 { grid-column: span 6; }
.c-8 { grid-column: span 8; }
.c-4 { grid-column: span 4; }

@media (max-width: 900px) {
  .c-7, .c-5, .c-6, .c-8, .c-4 { grid-column: span 12; }
}

/* ============================================================ 4. header */

/* Two rows stay on screen: one bar of --header-h (56px) and one sub-band of --tap (44px,
   --s6 on a phone). html { scroll-padding-top } is both plus their hairlines, so an anchor
   lands under them rather than behind them. */
/* A sticky box is held inside its containing block, so while <header> wrapped both rows
   the bar could travel the 45px of the sub-band and then left the screen with it. The
   sub-band is now a sibling <nav> after </header>, which leaves <header> holding one row:
   an ordinary box, sticky against <body>, at top:0 and no offset to keep in step with
   anything. The sub-band rolls away because it is below the header, not because a number
   pushed it. --header-h stays the height of this box and scroll-padding-top stays true. */
.top {
  position: sticky;
  top: 0;
  z-index: 40;
}
.top__bar {
  background: var(--surface);
  border-bottom: var(--hair) solid var(--line);
}
.top__inner {
  min-height: var(--header-h);
  display: flex;
  align-items: center;
  gap: var(--s5);
  flex-wrap: nowrap;
}
/* The bar sticks and so does the sub-band. Task 10 moved the sub-band out of <header>
   so the bar could stick at all, and that left the six page names rolling away after
   ~100px: the header was sticky and useless. A sticky sibling holds its own offset, so
   <header> stays one ordinary box at top:0 and the nav sits on top of --header-h.
   The nav is the scroll container on a phone; it needs no tabindex, because everything
   inside it is a link and tabbing to one scrolls it into view. */
.subnav {
  position: sticky;
  top: calc(var(--header-h) + var(--hair));
  z-index: 39;
  background: var(--surface);
  border-bottom: var(--hair) solid var(--line);
}
.subnav .inner { display: flex; }
/* The name is the mark: logo.svg, drawn once and used by reference — letters in the colour
   of the text, the dot a cage nut in --logo-nut (the accent when nothing sets it) — so it
   reads as one word, "super.am", with no gap before the dot. The mark takes the free space
   after it, which keeps the login and the button at the right edge when the languages are
   hidden on a phone. */
.wordmark {
  flex: none;
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  margin-right: auto;
  color: var(--ink);
}
.logo { display: block; height: var(--logo-h); width: auto; aspect-ratio: var(--logo-ratio); color: var(--ink); }
/* the way in for a customer: a link to the client area, which is its own application */
.top__login { flex: none; }
/* the order button stands in the bar twice, in two cells, and one of them is drawn: its full
   words where the row has room, and on a phone their last word, so that the button keeps one
   line in all three languages. Two cells and not two spans, because a check reads a run of
   inline text as one string */
.top__cta { flex: none; }
.top__cta--short { display: none; }
@media (max-width: 480px) {
  .top__cta:not(.top__cta--short) { display: none; }
  .top__cta--short { display: block; }
}
.top__login a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding-inline: var(--s2);
  font-size: var(--t-body-2);
  font-weight: var(--w-mid);
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.top__login a:hover, .top__login a:active { color: var(--accent-ink); }
/* The chrome speaks in the reading face: page names, languages and the footer are text to
   read, not stamps. The label voice, mono capitals, is spent inside the page (§7 budget). */
.nav { display: flex; gap: var(--s4); flex-wrap: wrap; }
.nav a {
  font-size: var(--t-body-2);
  color: var(--ink-2);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding-inline: var(--s1);
}
.nav a:hover, .nav a:active, .nav a[aria-current] { color: var(--accent-ink); }
.nav a[aria-current] { box-shadow: inset 0 -2px 0 0 var(--accent); }


.langs { display: flex; gap: var(--s1); align-items: center; }
.langs span, .langs a {
  font-size: var(--t-body-2);
  color: var(--ink-2);
  min-height: var(--tap);
  display: inline-flex;
  align-items: center;
  padding-inline: var(--s2);
}
.langs li + li::before { content: ""; }
/* a language that is built is a link; the one being read is marked, not linked; a
   language not built yet stays a name in the list */
.langs a { text-decoration: none; }
.langs a:hover, .langs a:active { color: var(--accent-ink); }
.langs [aria-current] { color: var(--ink); box-shadow: inset 0 -2px 0 0 var(--accent); }

/* ============================================================ 5. buttons and doors */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-height: var(--tap);
  padding: var(--s3) var(--s5);
  border-radius: var(--radius);
  border: var(--hair) solid transparent;
  font-family: var(--font-text);
  font-size: var(--t-body-2);
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.btn--primary { background: var(--accent-fill); color: var(--on-accent); }
.btn--primary:hover, .btn--primary:active { background: var(--accent-deep); color: var(--on-accent); }
.btn--ghost { background: var(--surface); color: var(--ink); border-color: var(--line-control); }
.btn--ghost:hover, .btn--ghost:active { border-color: var(--accent); color: var(--accent-ink); }

.doors { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s4); }
.door { display: flex; flex-direction: column; gap: var(--s3); }
.door p { margin: 0; font-size: var(--t-body-2); color: var(--ink-2); max-width: 34ch; }
@media (max-width: 560px) { .doors { grid-template-columns: 1fr; } }

/* ============================================================ 6. hero */

/* the first screen keeps the second tier's rhythm, 64px and 48px under 901px: two tiers, not three */
.hero { position: relative; padding-block: var(--band-pad-dense); overflow: hidden; overflow: clip; }
.rack-stage { position: relative; }
.rack-callout {
  background: var(--surface);
  border: var(--hair) solid var(--line);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius);
  padding: var(--s4);
}
.rack-callout b {
  font-family: var(--font-label);
  font-size: var(--t-mono);
  font-weight: var(--w-mid);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  display: block;
  margin-bottom: var(--s1);
}
.rack-callout p { margin: 0; font-size: var(--t-body-2); color: var(--ink-2); }
@media (min-width: 901px) {
  .rack-callout { position: absolute; left: 0; width: 48%; top: 42%; transform: translateY(-50%); z-index: 2; }
}
/* Between 901 and 1279 the stage is narrow enough that 48% of it puts the card's right
   edge on the elevation's U-axis label: at 1024 it ate 2px of "U24" and the U read as a J.
   One step back clears it at every width in the range; the leader line, which is drawn in
   the SVG and not by the card, simply becomes visible for its last few pixels. Above 1280
   the stage is wide enough on its own and the reviewed geometry is untouched. */
@media (min-width: 901px) and (max-width: 1279px) {
  .rack-callout { width: calc(48% - var(--s2)); }
}
@media (max-width: 900px) {
  .rack-stage { display: flex; flex-direction: column; }
  .rack-callout { order: 2; margin-top: var(--s4); }
}

.hero > .inner { position: relative; z-index: 1; }
.hero__sub {
  font-size: var(--t-body-2);
  color: var(--redline-ink);
  border-left: var(--hair) solid var(--redline);
  padding-left: var(--s3);
  margin: var(--s5) 0 var(--s6);
  max-width: 40ch;
}
/* where the service's price starts, said on its first screen beside the way in: the sentence
   in the reading face at the title size, each price in it in mono, the way a rate is set */
.hero__from { margin: 0 0 var(--s5); font-size: var(--t-h3); font-weight: var(--w-mid); line-height: 1.3; color: var(--ink); max-width: 34ch; }
.hero__from [data-price], .hero__from [data-price-of], .offer__from [data-price], .offer__from [data-price-of] { font-family: var(--font-label); font-weight: var(--w-bold); color: var(--accent-ink); }
.hero .display { margin-bottom: var(--s5); }
.hero .lead { margin-bottom: var(--s6); }


/* ============================================================ 7. drawings */

.fig { display: block; width: 100%; height: auto; }
.fig text {
  font-family: var(--font-label);
  font-size: var(--t-fig);
  letter-spacing: var(--tr-fig);
  fill: var(--ink-2);
}
.fig--wide text { font-size: var(--t-fig-lg); }
.fig .t-lg { font-size: var(--t-fig-lg); fill: var(--ink); font-weight: var(--w-mid); }
.fig .t-sm { font-size: var(--t-fig-sm); }
.fig--wide .t-sm { font-size: var(--t-fig); }
.fig .t-red { fill: var(--redline-ink); }
.fig .t-mid { text-anchor: middle; }   /* was .fig .fig .t-mid, which matches nothing: every
                                          middle-anchored label in the site was drawn from its
                                          x instead of around it, and NEAR AMSTERDAM ran 25
                                          units past the right edge of its own viewBox */
.fig .t-end { text-anchor: end; }
/* A drawing on a phone is drawn at --fig-max, and at that scale every drawn label stood at
   6–9px, under the smallest step of type. On a screen under 901px the drawing keeps its lines
   and gives its labels up: the legend, the caption, the step list and the route beside it,
   and the drawing's own title and description, already say what they said. The red marks go
   with them — a redline bracket (lines) and a red frame (a rect): a drawing carries no red mark
   without its label (DESIGN.md). Paper keeps both. */
@media screen and (max-width: 900px) { .fig text, .fig line.s-red, .fig rect.s-red { display: none; } }

.s-line   { stroke: var(--ink); stroke-width: var(--stroke); fill: none; }
.s-thin   { stroke: var(--line-2); stroke-width: var(--hair); fill: none; }
.s-accent { stroke: var(--accent); stroke-width: var(--stroke); fill: none; }
.s-red    { stroke: var(--redline); stroke-width: var(--stroke); fill: none; }
.s-dash   { stroke-dasharray: var(--dash-fibre); }
.s-hair   { stroke: var(--ink); stroke-width: var(--hair); fill: none; }
.f-surface{ fill: var(--surface); }
.f-grid   { fill: var(--grid); }
.f-accent { fill: var(--accent); }
.f-ink    { fill: var(--ink); }
.f-none   { fill: none; }

.c-power-a, .c-power-b, .c-copper {
  fill: none;
  stroke-width: var(--stroke);
}
.c-power-a { stroke: var(--code-power-a); }
.c-power-b { stroke: var(--code-power-b); stroke-dasharray: var(--dash-feed-b); }
.c-copper  { stroke: var(--code-copper); }

.legend { display: flex; flex-wrap: wrap; gap: var(--s4); margin-top: var(--s4); }
.legend li { display: inline-flex; align-items: center; gap: var(--s2); font-family: var(--font-label); font-size: var(--t-micro); color: var(--ink-2); }
.legend svg { flex: none; }

/* --- labels that outgrew the drawing ---------------------------------------
   <text> does not wrap and nothing constrains it: a name too long for the geometry it was
   drawn into runs out of the plate and over whatever is beside it. checks/lib/check.py
   holds the rule as a length — nothing over 16 characters inside svg.fig — and these two
   layouts are where the long ones went: the name is HTML, so the browser wraps it, and the
   drawing keeps the part that is actually drawn. */

/* the line over the named cells that used to be drawn: what they sit inside */
.scope__axis {
  display: flex;
  justify-content: space-between;
  gap: var(--s4);
  padding-bottom: var(--s1);
  font-family: var(--font-label);
  font-size: var(--t-micro);
  letter-spacing: var(--tr-fig);
  color: var(--ink-2);
}

/* a short index of places on this page: one link a line, ruled like the rows of a table */
.links { list-style: none; margin: 0; padding: 0; border-top: var(--hair) solid var(--line-2); max-width: var(--measure); }
.links li { border-bottom: var(--hair) solid var(--line); }
.links a { display: flex; align-items: center; min-height: var(--tap); padding-block: var(--s2); }

/* named cells that used to be drawn: each is as wide as the words in it */
.boxes { display: flex; flex-wrap: wrap; gap: var(--s2); margin: 0; padding: 0; list-style: none; }
.boxes li {
  border: var(--hair) solid var(--ink);
  background: var(--grid);
  border-radius: var(--radius);
  padding: var(--s2) var(--s3);
  font-family: var(--font-label);
  font-size: var(--t-micro);
  letter-spacing: var(--tr-fig);
  color: var(--ink-2);
}

/* a route: two ends and the line between them. The ends are boxes of text, so they are
   text boxes — bordered in HTML — and only the line, the stops and the open window are
   drawn. An end is never narrower than its longest word: at minmax(0, 1fr) NEAR AMSTERDAM
   and ANOTHER DATACENTER ran through their own border in a 5-column lane, and the Russian
   АМСТЕРДАМОМ ran a whole letter past it. The route between them gives up the width.
   One rule folds it, and it asks the figure, not the screen: below 360 px of figure, two
   ends at their longest word and two gaps leave the route too short to draw its stops and
   its window, so the route stands on end, the ends above and below it. That is a phone
   (a 390 px screen leaves 358 px) and the narrow lane at 901–1199 px alike. */
.route { display: grid; grid-template-columns: minmax(min-content, 1fr) minmax(0, 2.6fr) minmax(min-content, 1fr); gap: var(--s4); align-items: center; }
figure:has(> .route) { container: route / inline-size; }
@container route (max-width: 360px) { .route { grid-template-columns: 1fr; } }
.route__end {
  background: var(--surface);
  border: var(--stroke) solid var(--ink);
  border-radius: var(--radius);
  padding: var(--s3);
  text-align: center;
  font-family: var(--font-label);
  font-size: var(--t-mono);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--ink);
}

/* ============================================================ 8. the 46U elevation */

/* An elevation is a scale drawing: it is drawn at one width, and the plate that carries
   it is that width. The cap used to sit on the drawing while the plate grew with the lane,
   so the drawing stood as a strip in an empty field — FIG. 02 measured 0.29 of its plate at
   1440 px and 0.42 at 768 px. Now the plate is the cap and the drawing fills it. */
.plate--figure:has(.rack) { max-width: calc(var(--fig-max) + var(--s4) * 2); margin-inline: auto; }
.rack { display: block; width: 100%; height: auto; margin-inline: auto; }
.rack .u-slot { fill: var(--surface); stroke: var(--line); stroke-width: var(--stroke-fine); }
.rack .u-slot.is-filled { fill: var(--accent-soft); stroke: var(--accent); stroke-width: var(--stroke-fine); }
.rack .u-grid { fill: none; stroke: var(--grid); stroke-width: var(--stroke-fine); }
.rack .u-dev { opacity: 0; }
.rack .u-dev .dev-face { fill: var(--accent); }
.rack .u-dev .dev-vent { fill: var(--line-2); }
.rack .u-dev .dev-led  { fill: var(--line-2); }
.rack .u-slot.is-filled + .u-dev { opacity: 1; }
.rack .u-slot, .rack .u-dev { transition: fill var(--dur-1) linear, opacity var(--dur-1) linear; }
.rack .rail { fill: var(--paper); stroke: var(--line-2); stroke-width: var(--hair); }
.rack .frame { fill: none; stroke: var(--ink); stroke-width: var(--stroke); }

/* ============================================================ 9. the eight steps, and who
   carries the jobs (ADR 0052) */

/* The eight steps, once (R2): one dimension chain read left to right, a tick at the start of
   each step and the line running on to the next, four to a row on a wide screen, two in the
   middle, a column on a phone, where the chain stands upright on the left. The last step's
   tick is the run: the one bright fill on the strip, inside an --accent outline. */
.journey { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s7) var(--s5); }
.journey__step { position: relative; min-width: 0; padding-top: var(--s5); }
.journey__step::before {
  content: ""; position: absolute; top: var(--s1); left: 0; right: calc(-1 * var(--s5));
  border-top: var(--stroke) solid var(--accent);
}
.journey__step:nth-child(4n)::before, .journey__step:last-child::before { right: 0; }
.journey__step::after {
  content: ""; position: absolute; top: 0; left: 0; width: var(--s2); height: var(--s2);
  background: var(--surface); border: var(--stroke) solid var(--accent);
}
.journey__step:last-child::after { background: var(--accent-bright); }
.journey__n { display: block; font-family: var(--font-label); font-size: var(--t-mono); letter-spacing: var(--tr-label); color: var(--accent-ink); }
.journey__name { display: block; margin-top: var(--s1); font-size: var(--t-h3); line-height: 1.2; font-weight: var(--w-bold); color: var(--ink); }
.journey__body { margin: var(--s2) 0 0; font-size: var(--t-body-2); color: var(--ink-2); max-width: 34ch; }
@media (max-width: 1000px) {
  .journey { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .journey__step:nth-child(4n)::before { right: calc(-1 * var(--s5)); }
  .journey__step:nth-child(2n)::before, .journey__step:last-child::before { right: 0; }
}
@media (max-width: 560px) {
  .journey { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .journey__step { padding: 0 0 var(--s5) var(--s6); }
  .journey__step::before, .journey__step:nth-child(n)::before { top: var(--s1); bottom: 0; left: calc(var(--s1) - var(--stroke) / 2); right: auto; border-top: 0; border-left: var(--stroke) solid var(--accent); }
  .journey__step:last-child::before { display: none; }
}
/* the moment: the chain is drawn step by step, each tick set and its words written as the line
   reaches it — the order of the work, in the time it takes to read the numbers */
.journey__step:nth-child(1) { --i: 0; } .journey__step:nth-child(2) { --i: 1; }
.journey__step:nth-child(3) { --i: 2; } .journey__step:nth-child(4) { --i: 3; }
.journey__step:nth-child(5) { --i: 4; } .journey__step:nth-child(6) { --i: 5; }
.journey__step:nth-child(7) { --i: 6; } .journey__step:nth-child(8) { --i: 7; }
@keyframes chain-run { from { clip-path: inset(-4px 100% -4px -4px); } to { clip-path: inset(-4px); } }
@keyframes chain-drop { from { clip-path: inset(-4px -4px 100% -4px); } to { clip-path: inset(-4px); } }
@keyframes tick-set { from { opacity: 0; transform: scale(0.4); } to { opacity: 1; transform: none; } }
.journey.is-pending .journey__step::before, .journey.is-drawing .journey__step::before {
  animation: chain-run var(--dur-3) var(--ease) calc(var(--i) * var(--dur-draw) / 8) 1 backwards;
}
.journey.is-pending .journey__step::after, .journey.is-drawing .journey__step::after {
  animation: tick-set var(--dur-2) var(--ease) calc(var(--i) * var(--dur-draw) / 8) 1 backwards;
}
.journey.is-pending .journey__step > *, .journey.is-drawing .journey__step > * {
  animation: dim-in var(--dur-3) var(--ease) calc(var(--i) * var(--dur-draw) / 8 + var(--dur-1)) 1 backwards;
}
@media (max-width: 560px) {
  .journey.is-pending .journey__step::before, .journey.is-drawing .journey__step::before { animation-name: chain-drop; }
}
.journey.is-pending .journey__step::before, .journey.is-pending .journey__step::after,
.journey.is-pending .journey__step > * { animation-play-state: paused; }

/* Who carries the jobs (R1): the same jobs as the table beside it, one bar a job, stacked on
   the side that does them. Ordinary colocation piles every one of them on your team, in the
   annotation pen that means "your part"; here they stand on ours, in apricot. Its moment: the
   pile lands on your team bar by bar, and then, on our side, the same pile is lifted across to
   the engineers. The words are HTML, so each language sets its own; the drawing is a picture
   of the table and is hidden from assistive technology, which reads the table. */
.load {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)) var(--s3) repeat(2, minmax(0, 1fr));
  column-gap: var(--s2); padding: var(--s5) var(--s4) var(--s6);
}
.load__name { grid-row: 1; margin: 0 0 var(--s4); font-size: var(--t-body-2); font-weight: var(--w-mid); line-height: 1.3; color: var(--ink); align-self: end; }
.load__name--ordinary { grid-column: 1 / 3; }
.load__name--ours { grid-column: 4 / 6; }
.load__bin { grid-row: 2; display: flex; flex-direction: column-reverse; gap: var(--s1); border-bottom: var(--stroke) solid var(--ink-3); }
.load__bin:nth-of-type(1) { grid-column: 1; } .load__bin:nth-of-type(2) { grid-column: 2; }
.load__bin:nth-of-type(3) { grid-column: 4; } .load__bin:nth-of-type(4) { grid-column: 5; }
.load__bin--heavy { border-bottom-color: var(--redline); }
.load__job { flex: none; height: var(--s2); background: var(--redline); border: var(--hair) solid var(--redline); }
.load__bin--ours .load__job { background: var(--accent-soft); border-color: var(--accent); }
.load__who { grid-row: 3; margin: var(--s2) 0 0; font-size: var(--t-micro); line-height: 1.3; color: var(--ink-2); }
.load__who:nth-of-type(3) { grid-column: 1; } .load__who:nth-of-type(4) { grid-column: 2; }
.load__who:nth-of-type(5) { grid-column: 4; } .load__who:nth-of-type(6) { grid-column: 5; }
.load__job:nth-child(1) { --i: 0; } .load__job:nth-child(2) { --i: 1; } .load__job:nth-child(3) { --i: 2; }
.load__job:nth-child(4) { --i: 3; } .load__job:nth-child(5) { --i: 4; } .load__job:nth-child(6) { --i: 5; }
.load__job:nth-child(7) { --i: 6; } .load__job:nth-child(8) { --i: 7; } .load__job:nth-child(9) { --i: 8; }
.load__job:nth-child(10) { --i: 9; } .load__job:nth-child(11) { --i: 10; } .load__job:nth-child(12) { --i: 11; }
.load__job:nth-child(13) { --i: 12; }
@keyframes job-land { from { opacity: 0; transform: translateY(calc(-3 * var(--s2))); } to { opacity: 1; transform: none; } }
@keyframes job-lift { from { transform: translateX(calc(-100% - var(--s2))); background: var(--redline); border-color: var(--redline); } }
.load.is-pending .load__bin--heavy .load__job, .load.is-drawing .load__bin--heavy .load__job {
  animation: job-land var(--dur-2) var(--ease) calc(var(--i) * var(--dur-draw) / 28) 1 backwards;
}
.load.is-pending .load__bin--ours .load__job, .load.is-drawing .load__bin--ours .load__job {
  animation: job-lift var(--dur-3) var(--ease) calc(var(--dur-draw) / 2 + (12 - var(--i)) * var(--dur-draw) / 28) 1 backwards;
}
.load.is-pending .load__job { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .journey .journey__step::before, .journey .journey__step::after, .journey .journey__step > *, .load .load__job { animation: none; }
}

/* ============================================================ 10. spec tables */

.tablewrap { overflow-x: auto; border: var(--hair) solid var(--line); border-radius: var(--radius); background: var(--surface); }
/* a table set on a plate is already framed by the plate: a second hairline inside it read
   as a frame in a frame */
.plate .tablewrap { border-color: transparent; background: none; }
/* the price lists of pricing.html: every price column starts at the same x from one table
   to the next, instead of wherever the prose column beside it happened to end */
@media (min-width: 641px) { .spec--price td.n { width: 24%; } }
.tablewrap:focus-visible, .term:focus-visible { outline: var(--focus) solid var(--accent); outline-offset: 2px; }
.spec { width: 100%; border-collapse: collapse; font-size: var(--t-body-2); min-width: 520px; }
.spec caption { text-align: left; padding: var(--s3) var(--s3) 0; font-size: var(--t-body-2); font-weight: 600; color: var(--ink); }
.spec th, .spec td { text-align: left; padding: var(--s2) var(--s3); border-bottom: var(--hair) solid var(--line); vertical-align: top; }
.spec thead th {
  font-family: var(--font-label);
  font-size: var(--t-micro);
  font-weight: var(--w-mid);
  letter-spacing: var(--tr-thead);
  text-transform: uppercase;
  color: var(--ink-2);
  border-bottom: var(--hair) solid var(--line-2);
  white-space: nowrap;
}
/* Armenian column heads run twice the English length in uppercase mono; held on one line
   they pushed support's FIG. 02 (768) and FIG. 04 (390) past their own scroller */
:lang(hy) .spec thead th { white-space: normal; }
.spec tbody th {
  font-weight: 600;
  color: var(--ink);
  /* a share, not a cap, and never narrower than the longest word in the label: an
     uppercase mono label does not wrap on its own and used to push into the next cell */
  width: 22%;
  min-width: min-content;
  overflow-wrap: break-word;
}
.spec tbody tr:last-child th, .spec tbody tr:last-child td { border-bottom: 0; }
.spec .n { font-family: var(--font-label); font-variant-numeric: tabular-nums; }
.spec td.n { white-space: nowrap; }
/* a grouped cell is a list of short lines, not prose: on a wide lane it reads in two
   columns and the table stops running a thousand pixels down the page */
@media (min-width: 1000px) { .spec--group td ul { columns: 2; column-gap: var(--s5); } }
.spec td ul li { padding-left: var(--s4); position: relative; margin-bottom: var(--s1); break-inside: avoid; }
.spec td ul li::before { content: ""; position: absolute; left: 0; top: 0.7em; width: 8px; height: 1px; background: var(--line-2); }

/* the port and its commitment as one grid: a price where the pair is sold, a hatch where it
   is not, and the whole-port column, the one the big ports live in, set heavier */
.portgrid th, .portgrid td { text-align: right; }
.portgrid th:first-child { text-align: left; }
.portgrid tbody th { width: auto; white-space: nowrap; }
.portgrid td:last-child { font-weight: 600; }
.portgrid .portgrid__none { background: repeating-linear-gradient(135deg, var(--line) 0 var(--hair), transparent var(--hair) var(--s2)); }

.spec--group tbody th { width: 26%; vertical-align: top; }
.spec--compare td { width: 39%; }
.spec--compare td.is-ours { background: var(--accent-soft); }

@media (max-width: 640px) {
  .spec { min-width: 0; }
  /* the port grid only reads as a grid: it scrolls in its wrap rather than crushing columns */
  .spec.portgrid { min-width: 30rem; }
  .spec--stack, .spec--stack thead, .spec--stack tbody, .spec--stack tr, .spec--stack th, .spec--stack td { display: block; width: auto; }
  /* the table is display:block here, which leaves <caption> a shrink-to-fit box: the
     quote captions came out 105px wide and 112px tall on a phone, one word a line */
  .spec--stack caption { display: block; width: auto; }
  .spec--stack thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .spec--stack tbody tr { border-bottom: var(--hair) solid var(--line-2); padding: var(--s3) 0; }
  .spec--stack tbody th { width: auto; border-bottom: 0; padding-bottom: var(--s1); }
  .spec--stack td { border-bottom: 0; padding-block: var(--s1); }
  /* a row with nothing to say in a column does not print the column's name over a blank */
  .spec--stack td:empty { display: none; }
  .spec--stack td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-family: var(--font-label);
    font-size: var(--t-micro);
    letter-spacing: var(--tr-thead);
    text-transform: uppercase;
    color: var(--ink-2);
    margin-bottom: 2px;
  }
  .spec--compare td { width: auto; }
}
/* A price list folds to its name and its price on one line, and what it is under them.
   The column heads stay, as one ruled line over the list, so «per month» or «price» is
   said once for the table and not once a row; the middle head is read, not shown. */
@media (max-width: 640px) {
  .spec--price thead { position: static; width: auto; height: auto; overflow: visible; clip-path: none; }
  .spec--price tr { display: grid; grid-template-columns: minmax(40%, 1fr) auto; }
  .spec--price td.n { white-space: normal; }
  .spec--price thead tr { border-bottom: var(--hair) solid var(--line-2); }
  .spec--price thead th { border-bottom: 0; }
  .spec--price thead th:nth-child(2) { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .spec--price tr > :first-child { grid-column: 1; grid-row: 1; }
  .spec--price tr > :last-child { grid-column: 2; grid-row: 1; padding-left: var(--s4); text-align: right; }
  .spec--price td:not(:last-child) { grid-column: 1 / -1; grid-row: 2; color: var(--ink-2); }
  .spec--price td[data-label]::before { content: none; }
}

/* the numbers row, as a table of figures and their sources */
.spec--numbers .n { font-size: var(--t-body-2); font-family: var(--font-label); text-transform: none; letter-spacing: 0; }
.spec--numbers td:first-child { width: 34%; }

/* ============================================================ 11. the accent band
   Ticket 02 turned this band from a blue flood into a register. Nothing here repaints
   type any more: the band ground is paper-light, so --ink and --ink-2 inherit straight
   through. What is left is the apricot the band is drawn with. The old .band--blueprint
   half of each pair is the markup's historical name; see the file header. */

.band--accent .plate,
.band--accent .tablewrap { background: transparent; border-color: var(--accent); }
.band--accent .spec { background: transparent; }
.band--accent .spec th,
.band--accent .spec td { border-bottom-color: var(--line-2); }
.band--accent .spec thead th { border-bottom-color: var(--accent); }
.band--accent .spec--stack tbody tr { border-bottom-color: var(--line-2); }

/* ============================================================ 12. machine band */

/* Six rules used to stand here, one per class — .band--machine .h2, .lead, .caption,
   .chip, a, .open — and each of them painted every node inside the band, including the
   white cards standing on it: --machine-ink on a white callout measured 1.24:1. They are
   gone. The band re-points its tokens in tokens.css §2.5 and the light surfaces name the
   paper set back; the only thing left to say here is that colour is inherited from the
   token, because `color` itself is not a token and does not re-point with them. */
.band--machine .plate,
.band--machine .callout,
.band--machine .tablewrap,
.band--machine .on-paper { color: var(--ink); }

.term {
  background: var(--machine-panel);
  border: var(--hair) solid var(--machine-line);
  border-radius: var(--radius);
  overflow-x: auto;
}
.term pre {
  margin: 0;
  padding: var(--s5) var(--s4);
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  line-height: 1.5;
  color: var(--machine-ink);
  white-space: pre;
}
.term__list { padding: var(--s4); display: grid; gap: var(--s3); }
.term__list li { display: grid; grid-template-columns: var(--s5) minmax(0, 1fr); gap: var(--s3); font-size: var(--t-body-2); color: var(--machine-ink); }
.term__list .k { font-family: var(--font-mono); font-size: var(--t-micro); color: var(--machine-accent); padding-top: 3px; }
.term__list b { font-family: var(--font-label); font-size: var(--t-mono); font-weight: var(--w-mid); letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--machine-ink); display: block; margin-bottom: 2px; }
.term__list .d { color: var(--machine-ink-2); font-size: var(--t-body-2); margin: 0; }

/* ============================================================ 13. annotated lists */

.notes { display: grid; gap: var(--s4); }
.note {
  display: grid;
  grid-template-columns: var(--icon) minmax(0, 1fr);
  gap: var(--s3);
  border-bottom: var(--hair) solid var(--line);
  padding-bottom: var(--s4);
}
.note:last-child { border-bottom: 0; padding-bottom: 0; }
.note svg { margin-top: 5px; }
.note p { margin: 0; }
.note b {
  font-weight: 600;
  display: block;
  margin-bottom: 2px;
}
.mark-yes { stroke: var(--accent); stroke-width: var(--stroke); fill: none; }
.mark-no  { stroke: var(--redline); stroke-width: var(--stroke); fill: none; }


/* callout card — §5.2 */
.callout {
  background: var(--surface);
  border: var(--hair) solid var(--line);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius);
  padding: var(--s4);
}
.callout b {
  font-weight: 600;
  color: var(--ink);
  display: block;
  margin-bottom: var(--s1);
}
.callout p { margin: 0; font-size: var(--t-body-2); color: var(--ink-2); }
/* the lowest monthly price of a service, under its one line on the home page */
.callout .callout__from {
  margin-top: var(--s3);
  font-family: var(--font-label);
  font-size: var(--t-mono);
  color: var(--ink);
}

/* ============================================================ 14. FAQ, and the
   folding affordance every <details> on the site wears */

.faq { border-top: var(--hair) solid var(--line-2); }
.faq details { border-bottom: var(--hair) solid var(--line); }
.faq summary {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s3);
  align-items: start;
  padding: var(--s3) 0;
  min-height: var(--tap);
  cursor: pointer;
  list-style: none;
  font-size: var(--t-question);
  font-weight: 600;
  color: var(--ink);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover, .faq summary:active { color: var(--accent-ink); }
/* the line that closes a FAQ, once a page (UI-15 faq-tail): quieter than an answer */
.faq__tail { margin: var(--s5) 0 0; font-size: var(--t-body-2); color: var(--ink-2); }

/* The folding affordance, and it is the site's, not the FAQ's. The owner read the "+" as
   decoration, so the control says what it does in words and the state reads without colour:
   both strings stand in the delivered HTML, and exactly one of them is on screen — closed
   prints "Show the answer", open prints "Hide the answer". With no stylesheet the summary
   says both, which is wordy and still true. The border is what makes it read as a thing you
   press.

   Nothing below is scoped to .faq on purpose. Every <details> the site serves stands in a
   .faq today, and a rule written for that would show both words at once the first time a
   folding block is put anywhere else — a defect nobody would look for in a stylesheet. */
.chip--fold {
  display: inline-block;
  white-space: nowrap;
  text-transform: none;
  letter-spacing: var(--tr-caption);
  color: var(--ink-2);
  border: var(--hair) solid var(--line-control);
  border-radius: var(--radius);
  padding: var(--s1) var(--s2);
  font-family: var(--font-text);
  font-size: var(--t-mono);
  font-weight: var(--w-mid);
  letter-spacing: normal;
}
summary:hover .chip--fold, summary:focus-visible .chip--fold {
  color: var(--accent-ink);
  border-color: var(--accent);
}
details[open] > summary .fold-closed,
details:not([open]) > summary .fold-open { display: none; }
.faq .a { padding: 0 0 var(--s5); max-width: var(--measure); color: var(--ink-2); }

/* ============================================================ 15. form */

.form { display: grid; gap: var(--s4); }
.field { display: grid; gap: var(--s2); }
/* a field is named in the reading face, sentence case: the name is a question to the
   reader, not a part number */
.field label {
  font-size: var(--t-body-2);
  font-weight: var(--w-mid);
  color: var(--ink);
}
/* what qualifies a field's name is a line of its own under it, not a clause after a dash in
   the label: the name stays short, and the control is described by the line */
.field__hint { margin: 0; font-size: var(--t-body-2); color: var(--ink-2); }
.field input, .field select, .field textarea {
  font-family: var(--font-text);
  font-size: var(--t-body-2);
  color: var(--ink);
  background: var(--surface);
  border: var(--hair) solid var(--line-control);
  border-radius: var(--radius);
  padding: var(--s3);
  min-height: var(--tap);
  width: 100%;
}
.field textarea { min-height: var(--s9); resize: vertical; }
.field input::placeholder, .field textarea::placeholder { color: var(--ink-2); opacity: 1; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--accent); }
.form__note { font-size: var(--t-body-2); color: var(--ink-2); max-width: 52ch; }

/* ============================================================ 16. footer */

/* The footer is the drawing's title block: one plate, ruled into cells, that every sheet of
   the set carries in the same place. Row one: the mark and the languages · the eight pages ·
   the client area · the contact. Row two: the four facts of the entity and the facility.
   Then the general note (the compliance line) across the whole width, and the strip the
   sheet is signed with: the revision, the scale note, the sheet's own name.
   The rules between the cells are the plate's --line showing through a one-hair gap, so
   they meet cleanly at every crossing and at every width, and the cells stand on --surface.
   Four columns from 1001px, two down to 641px, one below. Every cell keeps the same inner
   margin, so the first line of each starts on one level and one left edge. */

.foot { background: var(--paper); border-top: var(--hair) solid var(--line-2); padding: var(--s8) 0; }
.foot__block {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--hair);
  background: var(--line); border: var(--hair) solid var(--line); border-radius: var(--radius);
  overflow: hidden;
}
.foot__cell { margin: 0; padding: var(--s6); min-width: 0; background: var(--surface); }
/* the four facts are one list and four cells: the list takes the row and lays its cells on
   the block's own columns */
.foot__facts { grid-column: 1 / -1; display: grid; grid-template-columns: inherit; gap: inherit; margin: 0; }
.foot__legal, .foot__end { grid-column: 1 / -1; }

.foot dl { margin: 0; }
.foot dt, .foot__h { margin: 0; font-size: var(--t-body-2); font-weight: var(--w-mid); color: var(--ink-2); }
.foot dd { margin: var(--s1) 0 0; font-size: var(--t-body-2); color: var(--ink); }

/* a link here is a name in a list, not a word in a sentence: ink, and underlined only under
   the pointer or the keyboard. The languages keep their own tab rule (section 4). */
.foot__pages a, .foot__client a, .foot__contact a {
  display: inline-flex; align-items: center; min-height: var(--s6);
  font-size: var(--t-body-2); color: var(--ink); text-decoration: none;
}
.foot__pages a:hover, .foot__client a:hover, .foot__contact a:hover,
.foot__pages a:focus-visible, .foot__client a:focus-visible, .foot__contact a:focus-visible { color: var(--accent-ink); text-decoration: underline; }

/* the mark at the head of its cell, the languages at its foot, both on the cell's left edge
   (a language name carries --s2 of padding either side, taken back here) */
.foot__brand { display: flex; flex-direction: column; justify-content: space-between; align-items: flex-start; gap: var(--s6); }
.foot__brand:has(.foot__twoam) { justify-content: flex-start; }
.foot__brand:has(.foot__twoam) .langs { margin-top: auto; }
.foot__brand .langs { flex-wrap: wrap; margin: 0 0 calc(-1 * var(--s2)) calc(-1 * var(--s2)); padding: 0; list-style: none; }

/* the eight pages, one under another; the row is --s6 tall and its first line is lifted by
   the half-row it pads above the words, so "Home" stands level with the other cells' heads */
.foot__pages { margin: calc(-1 * var(--s1)) 0 0; padding: 0; list-style: none; }
/* the sheet being read is pointed at the way a label points at a part: a short accent leader
   in the cell's margin, and the name in the accent */
.foot__pages a[aria-current] { position: relative; color: var(--accent-ink); font-weight: var(--w-mid); }
.foot__pages a[aria-current]::before {
  content: ""; position: absolute; top: 50%; right: calc(100% + var(--s1));
  width: var(--s3); height: var(--stroke); background: var(--accent);
}

.foot__client ul { margin: var(--s1) 0 0; padding: 0; list-style: none; }
/* the promise under the address is the quiet line of the cell: the same words as COLO-07,
   in the hint's colour, so the cell reads as an address and not as a paragraph */
.foot__promise { margin: var(--s3) 0 0; font-size: var(--t-body-2); color: var(--ink-2); }

/* the general note */
.foot__legal { padding-block: var(--s5); font-size: var(--t-body-2); color: var(--ink); }
.foot__legal b { font-weight: var(--w-bold); }

/* The strip: one cell per stamp, ruled like the block, and not three spans in a row —
   check.py reads a run of inline nodes as one string, and "REV. A" is six characters: it
   has to be a node of its own to count. The sheet's name keeps to the right-hand end, where
   a title block puts it; the note about paper (UI-15 print-note) is printed on paper only. */
.foot__cell.foot__end { display: flex; flex-wrap: wrap; padding: 0; list-style: none; }
.foot__end li { display: flex; align-items: center; padding: var(--s3) var(--s6); }
.foot__end li + li { border-left: var(--hair) solid var(--line); }
.foot__end .foot__sheet { margin-left: auto; }
.foot__end .foot__print { display: none; }

@media (pointer: coarse) {
  .foot__pages a, .foot__client a, .foot__contact a { min-height: var(--tap); }
  .foot__pages { margin-top: calc(-1 * (var(--tap) - var(--s5)) / 2); }
}
@media (max-width: 1000px) {
  .foot__block { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .foot__cell { padding: var(--s5); }
  .foot__end li { padding-inline: var(--s5); }
}
@media (max-width: 640px) {
  .foot { padding: var(--s6) 0; }
  .foot__block { grid-template-columns: minmax(0, 1fr); }
  /* one column of cells is long, so each cell holds its words closer: --s4 all round, the
     strip's stamps on the same inner edge, and the mark closer to the languages under it */
  .foot__cell { padding: var(--s4); }
  .foot__end li { padding-inline: var(--s4); }
  .foot__brand { gap: var(--s4); }
  /* the client area's two links share one row, and the contact's head and address one line */
  .foot__client ul { display: flex; flex-wrap: wrap; column-gap: var(--s5); }
  .foot__contact dl {
    display: flex; flex-wrap: wrap; align-items: baseline; column-gap: var(--s4);
    margin-top: calc(-1 * (var(--tap) - var(--s5)) / 2);
  }
  .foot__contact dd { margin-top: 0; }
  /* the four facts are one ruled cell and a list inside it, each head over its value, a short
     gap between one fact and the next, not four cells of their own */
  .foot__facts { gap: var(--s3); padding: var(--s4); background: var(--surface); }
  .foot__facts > .foot__cell { padding: 0; }
  /* the eight pages read down two short columns instead of one long one: the first as wide
     as its longest name, the second taking the rest, so no name wraps at phone width */
  .foot__pages { display: grid; grid-template-columns: max-content minmax(0, 1fr); grid-template-rows: repeat(4, auto); grid-auto-flow: column; column-gap: var(--s6); }
  /* a name that wraps (Legal and compliance, and longer in Armenian) keeps air from its neighbour */
  .foot__pages a { padding-block: var(--s1); }
  .foot__pages a, .foot__client a, .foot__contact a { min-height: var(--tap); }
  .foot__pages { margin-top: calc(-1 * (var(--tap) - var(--s5)) / 2); }
  /* the strip: the revision and the scale note side by side, the sheet's name under them */
  .foot__cell.foot__end { display: grid; grid-template-columns: auto minmax(0, 1fr); }
  .foot__end .foot__sheet { grid-column: 1 / -1; margin-left: 0; border-left: 0; border-top: var(--hair) solid var(--line); }
}

/* ============================================================ 17. specimen */


/* ============================================================ 18. misc blocks */

.stack-4 > * + * { margin-top: var(--s4); }
.rule { border: 0; border-top: var(--hair) solid var(--line); margin: var(--s4) 0; color: var(--line); }

/* a key list is a column of one-line facts; on a wide lane it reads in two and stops
   being the tallest thing in the band */
.keylist { display: grid; gap: var(--s3); }
@media (min-width: 1000px) { .keylist { display: block; columns: 2; column-gap: var(--s6); }
  .keylist li { break-inside: avoid; margin-bottom: var(--s3); } }
.keylist li { display: grid; grid-template-columns: var(--icon) minmax(0, 1fr); gap: var(--s3); font-size: var(--t-body-2); color: var(--ink-2); }
.keylist li::before { content: ""; width: 10px; height: 1px; background: var(--accent); margin-top: 0.75em; }
.keylist strong { color: var(--ink); }

.bar__track { display: block; height: 8px; background: var(--grid); border-radius: 1px; overflow: hidden; }

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

/* ============================================================ 19. late additions */

.cards3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s4); }
@media (max-width: 980px) { .cards3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px) { .cards3 { grid-template-columns: 1fr; } }
/* four cards read as two rows of two and two cards as a pair: a lone card under a row of
   three, or an empty third column beside two, reads as something missing */
@media (min-width: 621px) {
  .cards3:has(> :nth-child(4):last-child),
  .cards3:has(> :nth-child(2):last-child) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* the bar is bright apricot at 1.8:1 on its own track, so its edge, not its fill,
   carries the 3:1 — an --accent hairline. The figure beside it carries the number. */
.bar__fill { display: block; height: 100%; width: var(--w, 0%); background: var(--accent-bright); box-shadow: inset 0 0 0 var(--hair) var(--accent); }
.spec--latency tbody th { width: 30%; }
.spec--latency td:nth-child(2) { width: 46%; }
.spec--latency td:last-child { text-align: right; font-family: var(--font-label); }

@media (max-width: 900px) {
  /* the sticky bar stays one row of exactly --header-h: the language names are read in
     the footer rather than tapped in the header */
  /* One row sticks on a phone: the bar of --header-h. The eight page names are a block under
     it that scrolls away with the page, wrapped rather than slid sideways, so no name is
     ever cut at the screen's edge. */
  html { scroll-padding-top: calc(var(--header-h) + var(--hair)); }
  .subnav { position: static; }
  .top__inner { gap: var(--s3); }
  .top__inner .langs { display: none; }
  /* the button keeps its words on one line in all three languages: the row gives way
     around it (narrower gaps and padding on the narrowest phones), never inside it */
  .top__inner .btn { white-space: nowrap; }
  .nav { gap: 0 var(--s4); }
  .nav a { min-height: var(--s6); white-space: nowrap; }
  .rack-stage { display: flex; flex-direction: column; }
  .rack-callout { order: 2; margin-top: var(--s4); }
}
/* the narrowest phones: the mark, the login and the button still share one row of
   --header-h in all three languages */
@media (max-width: 400px) {
  .top__inner { gap: var(--s2); }
  .top .logo { height: var(--logo-h-sm); }
  .top__login a { padding-inline: var(--s1); }
  .top__inner .btn { padding-inline: var(--s3); }
}
/* 320px: Գնառաջարկ, the longest short word of the three languages, ran 9px past the screen's
   edge; the row gives the last of its air around the button, never inside its word */
@media (max-width: 360px) {
  .top__inner { gap: var(--s1); }
  .top__login a { padding-inline: 0; }
  .top__inner .btn { padding-inline: var(--s2); }
}
@media (max-width: 640px) {
  .spec--latency tbody tr { display: grid; grid-template-columns: 1fr auto; align-items: center; }
  .spec--latency td:nth-child(2) { grid-column: 1 / -1; }
  .spec--latency td:last-child { text-align: left; }
}

/* ============================================================ 20. spacing utilities
   The only vertical offsets used in the markup. Every value is a step of the scale in
   tokens.css; the markup carries no size of its own. */

.mt-0 { margin-top: 0; }
.mt-4 { margin-top: var(--s4); }
.mt-5 { margin-top: var(--s5); }
.mt-6 { margin-top: var(--s6); }
.mt-7 { margin-top: var(--s7); }
.m-0  { margin: 0; }
.lead-in { font-size: var(--t-lead); line-height: 1.6; }
/* a lead set inside a callout is still the lead: .callout p is the card's small print */
.callout .lead-in { font-size: var(--t-lead); line-height: var(--lh-lead); color: var(--ink); }

/* ============================================================ 21. the configurator,
   the quote and the order form

   Both service pages carried these rules as a page-local <style> while three pages were
   being built against this file at once. They are one set now. The two copies had drifted
   apart on the same node, and the drift is settled here rather than averaged: the refusal
   is .form__err on both pages, the aria-invalid border stands on both, and every reset
   button names the hint that follows it. Every value is a token. */

[data-build-part] { opacity: 0.16; transition: opacity var(--dur-1) var(--ease); }
[data-build-part].is-built { opacity: 1; }
.build-frame { stroke: var(--line-2); fill: none; stroke-width: var(--stroke); }
[data-build].is-assembled .build-frame { stroke: var(--accent); }

.svc summary { font-weight: var(--w-body); }
.svc summary b { font-weight: 600; }
.svc .a { max-width: none; padding: var(--s4) 0 var(--s6); color: var(--ink); }
.folds .a { max-width: none; }

.cfg__grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--s8); align-items: start; }
.cfg__set { border: 0; padding: 0; margin: 0; min-width: 0; }
.cfg__set + .cfg__set { margin-top: var(--s6); }
.cfg__legend { padding: 0; font-size: var(--t-body-2); font-weight: var(--w-mid); color: var(--ink); }
.cfg__opts { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s3); }
.cfg__opt { position: relative; }
.cfg__opt input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.cfg__opt span {
  display: flex; align-items: center; min-height: var(--tap);
  padding: var(--s2) var(--s4); font-size: var(--t-body-2);
  background: var(--surface); border: var(--hair) solid var(--line-control); border-radius: var(--radius);
  transition: border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.cfg__opt input:checked + span { border-color: var(--accent); background: var(--accent-wash); color: var(--accent-ink); }
.cfg__opt input:focus-visible + span { outline: var(--focus) solid var(--accent); outline-offset: 2px; }
.cfg__nums { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s4); margin-top: var(--s4); }
/* Two to a row, and never one left alone in the last: the last field shown, when it stands
   at an odd place among the fields shown, takes the whole row. Colocation shows five with a
   rack format (committed power is one) and four with 1U, 2U or 4U, so Term takes the row
   only when it would otherwise stand alone. Counted with :nth-child(… of …), because a field
   the format hides is still a child; an engine without it leaves the grid as it was. */
.cfg__nums > .field:not([hidden]):nth-last-child(1 of .field:not([hidden])):nth-child(odd of .field:not([hidden])) { grid-column: 1 / -1; }
/* the two fields of a row share their three lines — name, hint, control — so a hint that
   wraps to a second line does not push its control below its neighbour's */
.cfg__nums > .field { grid-row: span 3; grid-template-rows: subgrid; row-gap: var(--s2); }
.cfg__reset { justify-self: start; }

/* one slider rule for all four configurators: the track is the control, so the input
   border and ground that dress a text field are taken back off it */
/* The whole box is the target: a range input moves its thumb from a press anywhere inside
   it, so --tap here buys a 44px-tall target across the full width of the control, not just
   around the thumb glyph. The glyph itself stays the browser's: drawing it means
   appearance:none, which also takes away the native track that accent-color paints and that
   the print register leans on, and puts a second slider design into a file that has none. */
.field input[type="range"] { border: 0; background: transparent; padding: 0; min-height: var(--tap); accent-color: var(--accent); }
.field input[type="checkbox"] { width: var(--icon); height: var(--icon); min-height: 0; accent-color: var(--accent); }
.field output { font-family: var(--font-mono); font-size: var(--t-body-2); color: var(--accent-ink); }

.cfg__rack .u-slot.is-built { fill: var(--accent-soft); stroke: var(--accent); }
.cfg__rack .u-slot.is-built + .u-dev { opacity: 1; }
.cfg__rack .env { opacity: 0; }
.cfg__rack .env--quarter { opacity: 1; }
.cfg:has(#fmt-half:checked) .cfg__rack .env--quarter,
.cfg:has(#fmt-full:checked) .cfg__rack .env--quarter { opacity: 0; }
/* a configurator field or note that the chosen format does not use; .field is a grid */
.cfg [hidden] { display: none; }
.cfg:has(#fmt-half:checked) .cfg__rack .env--half,
.cfg:has(#fmt-full:checked) .cfg__rack .env--full { opacity: 1; }
/* a line priced on the written quote says so in a plain sentence, which has to wrap */
.quote td.n .quote__held { white-space: normal; }
.cfg__rack.is-assembled .frame { stroke: var(--accent); }

/* the shelf, the bay and the pair that lights up.

   A part is one row: its name, then the minus, the count and the plus. The two buttons
   stand either side of the number, the same size and bordered like every control, and each
   moves the count one step at once (owner, 30 September 2026: minus left, plus right). The
   name and the count are one live region, .part__read, laid on the row's own columns with
   subgrid: a screen reader hears "Power 5" once, and on screen the number sits between the
   buttons. The part itself is what a pointer drags into the bay; a touch never does.
   Everything the mechanism needs is a class on markup that already stands in the page, so
   with the script off both buttons stay disabled, the shelf is a list of what the
   configuration holds, the bay is the drawing it fills, and the form fields below it are
   the way to change it. */

.parts { list-style: none; margin-left: 0; padding: 0; display: grid; gap: var(--s2); }
.part {
  display: grid; grid-template-columns: minmax(0, 1fr) var(--tap) auto var(--tap);
  align-items: center; column-gap: var(--s2);
  padding: var(--s1) var(--s1) var(--s1) var(--s4);
  background: var(--surface); border: var(--hair) solid var(--line-control); border-radius: var(--radius);
  user-select: none; -webkit-user-select: none;
  transition: border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}
.part__read { grid-column: 1 / 4; grid-row: 1; display: grid; grid-template-columns: subgrid; align-items: baseline; min-width: 0; }
.part__name { grid-column: 1; min-width: 0; font-size: var(--t-body-2); overflow-wrap: break-word; }
/* four figures wide whatever the count, so the plus does not step sideways at 10 or 1,000 */
.part__n {
  grid-column: 3; min-width: 4ch; text-align: center;
  font-family: var(--font-mono); font-size: var(--t-body); font-variant-numeric: tabular-nums; color: var(--accent-ink);
}
/* an engine without subgrid gets the name and the count together, then the two buttons */
@supports not (grid-template-columns: subgrid) {
  .part__read { grid-column: 1; display: flex; justify-content: space-between; gap: var(--s2); }
}
.part__btn {
  grid-row: 1;
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--tap); height: var(--tap); padding: 0;
  background: var(--surface); color: var(--ink);
  border: var(--hair) solid var(--line-control); border-radius: var(--radius);
  cursor: pointer;
  transition: border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.part__btn[data-assemble-pull] { grid-column: 2; }
.part__btn[data-assemble-add] { grid-column: 4; }
.part__btn:not([disabled]):hover { border-color: var(--accent); color: var(--accent-ink); }
.part__btn:not([disabled]):active { background: var(--accent-wash); }
.part__btn:focus-visible { outline: var(--focus) solid var(--accent); outline-offset: 2px; }
/* the buttons ship disabled and assemble.js turns on the ones that can act: with no script
   they are still there to read, and they do not offer a press that does nothing; at a
   floor or a ceiling only the one that has run out goes quiet */
.part__btn[disabled] { cursor: default; color: var(--ink-3); border-color: var(--line); }
.part__sign { display: block; width: var(--icon); height: var(--icon); fill: none; stroke: currentColor; stroke-width: var(--stroke); }

/* a part the script can move can be carried to the bay as well, by a pointer */
.part:has(> .part__btn:not([disabled])) { cursor: grab; }
.part.is-lit { border-color: var(--accent); background: var(--accent-wash); }
.part.is-dragging {
  position: relative; z-index: 2; cursor: grabbing; border-color: var(--accent);
  transform: translate(var(--dx, 0px), var(--dy, 0px));
}

/* the quote line and the part it came from are one pair, lit from either end */
.quote tr.is-lit > th, .quote tr.is-lit > td { background: var(--accent-wash); }

.cfg__bay { position: relative; border: var(--stroke) dashed transparent; border-radius: var(--radius); }
.cfg__bay.is-target, .cfg__bay.is-lit { border-color: var(--accent); }
.cfg__bay.is-target { cursor: copy; }
.cfg__bay.is-target.is-over { background: var(--accent-wash); }
.cfg__bay:focus-visible { outline: var(--focus) solid var(--accent); outline-offset: 2px; }

/* A part put in or taken out, by a button or a drop, is acknowledged where it lands: the
   line it pays for takes --accent-soft, and the drawing that counts it takes an --accent
   frame, for a beat (--dur-2, held by assemble.js) and then let go over --dur-3. Not a
   moment of its own, a state let go slowly; under reduced motion the script adds nothing. */
.quote tr[data-quote-line] > th, .quote tr[data-quote-line] > td { transition: background var(--dur-3) var(--ease); }
.quote tr.is-ack > th, .quote tr.is-ack > td { background: var(--accent-soft); transition: none; }
.cfg__bay > .plate { transition: border-color var(--dur-3) var(--ease); }
.cfg__bay.is-ack > .plate { border-color: var(--accent); transition: none; }

/* the colocation quote is a four-column table and scrolls in its own container; the
   home-page quotes stack on a phone instead, so the floor is theirs to keep */
.quote:not(.spec--stack) { min-width: 420px; }
.quote .n { text-align: right; font-family: var(--font-label); }
/* the quote's own column heads wrap: `.spec thead th { white-space: nowrap }` held
   "How much: units, racks or kW" on one 260px line and starved the price column */
.quote thead th { white-space: normal; }
.quote thead th:last-child, .quote td.n:last-child { width: 34%; }
.quote tfoot th, .quote tfoot td { border-top: var(--stroke) solid var(--ink); font-weight: var(--w-mid); }

/* the refusal: one class on both service pages, and the field it is about says so itself */
.form__err { margin: var(--s2) 0 0; font-size: var(--t-body-2); color: var(--redline-ink); max-width: var(--measure); }
.form__err b, .form__err strong { font-weight: var(--w-bold); }
.field input[aria-invalid="true"], .field select[aria-invalid="true"], .field textarea[aria-invalid="true"] { border-color: var(--redline); }

.order__done { border: var(--hair) dashed var(--accent); border-radius: var(--radius); padding: var(--s5); }
.order__aside { margin: var(--s2) 0 0; font-size: var(--t-body-2); color: var(--ink-2); }
.order__ref { font-family: var(--font-mono); font-size: var(--t-h3); color: var(--accent-ink); display: block; margin-top: var(--s2); }
/* what the server answered: the script's line for a request that did not go out ships
   hidden and is revealed by order.js; the two lines a browser without the script lands on
   stand in the markup and show only as the target of the server's 303 */
.order__sent, .order__failed { display: none; }
.order__sent:target, .order__failed:target { display: block; }
.btn[aria-busy="true"] { cursor: progress; }

@media (max-width: 900px) {
  .cfg__grid { grid-template-columns: minmax(0, 1fr); }
  .cfg__nums { grid-template-columns: minmax(0, 1fr); }
}
/* At 900px and under the configurator is one column and its quote stands at the foot, below
   every control. The quote folds to a list — the line's name and its sum on one line, the
   quantity and the unit under them. The table keeps its own box and its foot keeps the
   total: a table that gives up its box (display: contents) stops being a table to a
   screen reader in Safari, so what rides the screen's edge is a copy (.cfg__stick below). */
@media (max-width: 900px) {
  .cfg .quote caption { padding-bottom: var(--s2); }
  .cfg .quote thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .cfg .quote tbody, .cfg .quote tfoot { display: block; }
  .cfg .quote tbody { border-top: var(--hair) solid var(--line-2); }
  .cfg .quote tr {
    display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
    column-gap: var(--s2); align-items: baseline;
    padding: var(--s3); border-bottom: var(--hair) solid var(--line);
  }
  .cfg .quote tr[hidden] { display: none; }
  .cfg .quote th, .cfg .quote td { display: block; width: auto; padding: 0; border: 0; }
  .cfg .quote th { grid-column: 1 / 3; grid-row: 1; }
  /* width: auto — the desktop share (`.quote td.n:last-child { width: 34% }`) outranks the
     plain reset above and held «in the written proposal» to a 110px column, a word a line */
  .cfg .quote td.n:last-child { grid-column: 3; grid-row: 1; width: auto; max-width: var(--cell-max); padding-left: var(--s4); text-align: right; }
  .cfg .quote td.n:not(:last-child) { grid-column: 1; grid-row: 2; }
  .cfg .quote td:not(.n) { grid-column: 2; grid-row: 2; }
  .cfg .quote td:not(:last-child) { font-size: var(--t-body-2); color: var(--ink-2); }
  /* a sum still in words — «in the written proposal», «on request: above 7 kW…» — takes a
     line of its own under the row instead of squeezing the name into a third of it */
  .cfg .quote td.n:last-child:has(> .quote__held:not([hidden])) { grid-column: 1 / -1; grid-row: 3; max-width: none; padding-left: 0; text-align: left; }
  .cfg .quote tr:has(> td.n:last-child > .quote__held:not([hidden])) > th { grid-column: 1 / -1; }
  .cfg .quote tfoot tr:first-child { border-top: var(--stroke) solid var(--ink); border-bottom: 0; }
  /* The monthly total rides the bottom edge of the screen while the configurator is on it
     and the total's own row is still below: one line, name and sum. It is a copy, hidden
     from assistive technology and shipped hidden; concept-a.js fills it from the row and
     shows it. With no script the row in the table is the only total, as on paper. */
  .cfg__stick {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 3;
    display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline;
    column-gap: var(--s4);
    margin: 0; padding: var(--s3) var(--margin);
    background: var(--surface); border-top: var(--stroke) solid var(--ink);
    font-size: var(--t-body-2); font-weight: var(--w-mid); color: var(--ink);
  }
  .cfg__stick .n { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
}
@media (min-width: 901px) { .cfg .cfg__stick { display: none; } }
@media (prefers-reduced-motion: reduce) {
  .cfg__opt span, .cfg__rack .u-slot, .cfg__rack .u-dev, .part, .part__btn { transition: none; }
}


/* The four-column quote keeps a 420px floor in a desktop lane. On a phone that floor is
   what pushed the price column off the screen, so the table shrinks to its own content.
   It stands below the floor because the floor is declared with the same weight. */
@media (max-width: 900px) { .quote:not(.spec--stack) { min-width: 0; } }

/* Pricing, FIG. 02 — the format picker. Picking a format lays the accent-soft ground under
   its row; no script, and without :has() every row simply stays on paper. */
/* the picked format lights its own row and every row elsewhere on the page that prices
   the same format: setup, meters, included hours. CSS only, so the page is whole without JS */
body:has(input[name="pick-format"][value="1u"]:checked) :is(tr[data-pick-row="1u"], tr[data-pick-for~="1u"]) > *,
body:has(input[name="pick-format"][value="2u"]:checked) :is(tr[data-pick-row="2u"], tr[data-pick-for~="2u"]) > *,
body:has(input[name="pick-format"][value="4u"]:checked) :is(tr[data-pick-row="4u"], tr[data-pick-for~="4u"]) > *,
body:has(input[name="pick-format"][value="quarter-rack"]:checked) :is(tr[data-pick-row="quarter-rack"], tr[data-pick-for~="quarter-rack"]) > *,
body:has(input[name="pick-format"][value="half-rack"]:checked) :is(tr[data-pick-row="half-rack"], tr[data-pick-for~="half-rack"]) > *,
body:has(input[name="pick-format"][value="full-rack"]:checked) :is(tr[data-pick-row="full-rack"], tr[data-pick-for~="full-rack"]) > * { background: var(--accent-soft); }
body:has(input[name="pick-format"][value="1u"]:checked) :is(tr[data-pick-row="1u"], tr[data-pick-for~="1u"]) > th,
body:has(input[name="pick-format"][value="2u"]:checked) :is(tr[data-pick-row="2u"], tr[data-pick-for~="2u"]) > th,
body:has(input[name="pick-format"][value="4u"]:checked) :is(tr[data-pick-row="4u"], tr[data-pick-for~="4u"]) > th,
body:has(input[name="pick-format"][value="quarter-rack"]:checked) :is(tr[data-pick-row="quarter-rack"], tr[data-pick-for~="quarter-rack"]) > th,
body:has(input[name="pick-format"][value="half-rack"]:checked) :is(tr[data-pick-row="half-rack"], tr[data-pick-for~="half-rack"]) > th,
body:has(input[name="pick-format"][value="full-rack"]:checked) :is(tr[data-pick-row="full-rack"], tr[data-pick-for~="full-rack"]) > th { box-shadow: inset var(--stroke) 0 0 var(--accent); }
/* a two-column table of short lines sits in a hero plate narrower than the 520px a
   spec table asks for; it wraps instead of scrolling a few pixels in its container */
.spec--fit { min-width: 0; }

/* Support: what we do and what we do not, side by side, a rule between them. */
.boundary .h3 { margin: 0 0 var(--s4); }
@media (min-width: 901px) { .boundary__side--not { border-left: var(--hair) solid var(--line); padding-left: var(--s6); } }
@media (max-width: 900px) { .boundary__side--not { margin-top: var(--s6); } }


/* ============================================================ 23. illustrations, motion,
   and the Armenian case

   An illustration is a drawing sheet: four corner ticks and the picture, and no word of its
   own — alt="", because the text beside it already says everything it shows. Paper pictures
   stand on paper and white, the two dark ones on the dark band. A mask fades each picture's
   edge into the ground it stands on, so its own ground (a shade lighter than --machine-bg,
   a faint ruling on paper) never reads as a plate or as a hole. */
.sheet {
  --tick: var(--s4);
  --tick-ink: var(--ink-3);
  margin: 0;
  padding: var(--s4);
  display: grid;
  justify-items: center;
  background:
    linear-gradient(var(--tick-ink), var(--tick-ink)) left top / var(--tick) var(--hair) no-repeat,
    linear-gradient(var(--tick-ink), var(--tick-ink)) left top / var(--hair) var(--tick) no-repeat,
    linear-gradient(var(--tick-ink), var(--tick-ink)) right top / var(--tick) var(--hair) no-repeat,
    linear-gradient(var(--tick-ink), var(--tick-ink)) right top / var(--hair) var(--tick) no-repeat,
    linear-gradient(var(--tick-ink), var(--tick-ink)) left bottom / var(--tick) var(--hair) no-repeat,
    linear-gradient(var(--tick-ink), var(--tick-ink)) left bottom / var(--hair) var(--tick) no-repeat,
    linear-gradient(var(--tick-ink), var(--tick-ink)) right bottom / var(--tick) var(--hair) no-repeat,
    linear-gradient(var(--tick-ink), var(--tick-ink)) right bottom / var(--hair) var(--tick) no-repeat;
}
.sheet img {
  display: block;
  width: 100%;
  height: auto;
  -webkit-mask-image: var(--sheet-fade);
  -webkit-mask-composite: source-in;
  mask-image: var(--sheet-fade);
  mask-composite: intersect;
}
/* the wide sheet that opens the second band of a service page: the drawing keeps its own
   proportions at a fixed height, and the sheet around it is the page's paper */
.sheet--wide { margin-bottom: var(--s6); padding-block: var(--s3); }
.sheet--wide img { width: auto; max-width: 100%; height: var(--sheet-h-wide); }
/* a sheet at a fixed picture height is as wide as its picture, so its corner ticks hold the
   drawing and not the lane around it */
.sheet--wide, .sheet--hero { width: fit-content; max-width: 100%; margin-inline: auto; }
/* the right-hand column of a first screen: the drawing above the plate it stands beside */
.sheet--hero { margin-bottom: var(--s5); }
.sheet--hero img { width: auto; max-width: 100%; height: var(--sheet-h-hero); }
/* 404 (ERR-01): the first-screen sheet with nothing drawn on it — the corner ticks hold an
   empty field of the picture's height, and FIG. 404 beside it says it was left so */
.sheet--blank { width: 100%; height: var(--sheet-h-hero); margin-bottom: var(--s5); }
.nf__fig { color: var(--accent-ink); }
.nf__pages .keylist { margin-top: var(--s4); }

/* the line under the two ways to hold the hardware: a note, not a third way */
.sidenote { font-size: var(--t-body-2); color: var(--ink-2); max-width: var(--measure); }
.sidenote strong { color: var(--ink); }

/* Motion: three moments and no more, each played once, when its drawing first comes into
   view — concept-a.js puts .is-drawing on a [data-draw] figure then. With no script, and
   under prefers-reduced-motion: reduce, the class never comes and each drawing stands in
   its finished state; section 18 cuts every duration besides. U24 — the height the hero
   points at — pulses three times and rests. */
@keyframes u-pulse { 0%, 100% { fill: var(--ink-2); } 50% { fill: var(--accent-ink); } }
.is-drawing .pulse { animation: u-pulse var(--dur-pulse) var(--ease) 3; }
/* the rear elevation's cables are run in from the top, down the rails, the way they are
   dressed: the patch panel first, then each feed and every cord it gives a machine */
@keyframes cable-run { from { clip-path: inset(-4px -4px 100% -4px); } to { clip-path: inset(-4px); } }
.is-pending .cables, .is-drawing .cables { animation: cable-run var(--dur-draw) var(--ease) 1 backwards; }
/* the support dial is swept in once, clockwise from twelve, the way its hand would travel;
   the sweep is one more layer of the sheet's edge mask, and at rest it covers everything */
@property --sweep { syntax: '<angle>'; inherits: false; initial-value: 360deg; }
@keyframes sweep { from { --sweep: 0deg; } to { --sweep: 360deg; } }
.sheet--dial img {
  -webkit-mask-image: conic-gradient(from 0deg at 51% 45%, var(--ink) var(--sweep), transparent 0), var(--sheet-fade);
  -webkit-mask-composite: source-in, source-in;
  mask-image: conic-gradient(from 0deg at 51% 45%, var(--ink) var(--sweep), transparent 0), var(--sheet-fade);
  mask-composite: intersect;
}
.sheet--dial.is-pending img, .sheet--dial.is-drawing img { animation: sweep var(--dur-draw) var(--ease) 1 backwards; }
/* from the script's arrival to its moment, a drawing not yet seen holds the moment's first
   frame: the same animation, paused at its start, so the frame is written once, in the
   keyframes, and plays on from there when .is-pending gives way to .is-drawing. With no
   script, and under reduced motion, .is-pending never comes */
.is-pending .cables, .sheet--dial.is-pending img { animation-play-state: paused; }

/* Armenian has no capitals to shout with: labels, heads and names stay in the case they are
   written in. Its spacing is not undone here selector by selector — every label tracks by a
   --tr-* token and takes its face from --font-label, and tokens.css re-points both under
   :lang(hy), the way .band--machine re-points its colours */
:lang(hy) *, :lang(hy) *::before { text-transform: none !important; }

/* ============================================================ 24. the two AMs, the three
   services, and the cloud next to five others (ADR 0050)

   The home page's first screen is built around one drawing: Armenia, where we are from, and
   Amsterdam, where your servers are, as the two ends of one dimension line laid across the
   whole sheet, with super.am standing on it and the public probe round trip written under it
   as the line's dimension. It is drawn in the house's own terms: the two AMs in the display
   face at the largest size on the site, the line in the annotation pen with a tick at each
   end, the figure under it in mono and in the same pen. The Armenian AM takes the apricot —
   the one place the origin speaks in the design — and the Amsterdam AM the ink. The words are
   HTML, so every language sets its own and nothing has to fit a viewBox.

   The first screen is one grid (.opening) and the drawing is its own row: on a wide screen
   the answer and the two doors stand above it and the drawing closes the screen across the
   full measure; on a phone the drawing follows the heading, so the two AMs are on the first
   screen at 390px as well. The markup order is the phone's order — heading, drawing, answer,
   doors — and a reader of the markup meets the same sequence. */
.opening {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  grid-template-areas: "title doors" "lead doors" "fig fig";
  column-gap: calc(var(--gutter) * 3);
}
.opening__title { grid-area: title; }
.opening__lead { grid-area: lead; margin-bottom: 0; }
.hero .opening__lead { margin-bottom: 0; }
.opening__doors { grid-area: doors; align-self: end; }
.opening__doors .doors { grid-template-columns: 1fr; }
.opening__fig { grid-area: fig; margin: var(--s7) 0 0; }
@media (max-width: 900px) {
  .opening { grid-template-columns: minmax(0, 1fr); grid-template-areas: "title" "fig" "lead" "doors"; }
  .opening__fig { margin: 0 0 var(--s6); }
  .opening__doors { margin-top: var(--s6); }
  .opening__doors .doors { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) { .opening__doors .doors { grid-template-columns: 1fr; } }

/* the drawing: AM | the line | AM on one row, each place named under its AM and no wider
   than it (min-content: the AM is one word, so the words under it wrap to its width), the mark
   on the line and the dimension under it; the caption is the drawing's title, across the foot */
.twoam {
  display: grid;
  grid-template-columns: min-content minmax(0, 1fr) min-content;
  column-gap: var(--s5);
  padding: var(--s7) var(--s7) var(--s6);
}
.twoam__end { display: flex; flex-direction: column; gap: var(--s4); min-width: 0; }
.twoam__end--to { align-items: flex-end; text-align: right; }
.twoam__am {
  display: block;
  font-size: var(--t-am);
  font-weight: var(--w-bold);
  line-height: 0.8;
  letter-spacing: -0.04em;
  color: var(--ink);
}
.twoam__end--from .twoam__am { color: var(--accent-ink); }
.twoam__place { margin: 0; font-size: var(--t-h3); font-weight: var(--w-bold); line-height: 1.2; color: var(--ink); }
.twoam__note { margin: var(--s1) 0 0; font-size: var(--t-body-2); color: var(--ink-2); }
/* the span: its first row is exactly as tall as an AM, so the line runs at the letters' middle */
.twoam__span {
  display: grid;
  grid-template-rows: calc(var(--t-am) * 0.8) auto;
  justify-items: center;
  min-width: 0;
}
.twoam__line { grid-area: 1 / 1; justify-self: stretch; position: relative; }
.twoam__line::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: calc(50% - var(--stroke) / 2);
  border-top: var(--stroke) solid var(--redline);
}
.twoam__line::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: calc(50% - var(--s4));
  height: var(--s6);
  border-inline: var(--stroke) solid var(--redline);
}
.twoam__mid { display: contents; }
/* the mark stands on the line, knocked out of it the way a plate's corner marks are */
.twoam__mid .logo {
  grid-area: 1 / 1;
  align-self: center;
  position: relative;
  height: var(--logo-h-lg);
  padding-inline: var(--s3);
  box-sizing: content-box;
  background: var(--surface);
}
.twoam__ms { margin: var(--s4) 0 0; font-family: var(--font-label); font-size: var(--t-h3); font-weight: var(--w-mid); color: var(--redline-ink); text-align: center; }
.twoam__mid .twoam__note { margin: 0; text-align: center; }
.twoam__cap {
  grid-column: 1 / -1;
  margin-top: var(--s6);
  padding-top: var(--s4);
  border-top: var(--hair) solid var(--line);
  font-size: var(--t-lead);
  line-height: 1.4;
  color: var(--ink);
}
@media (max-width: 900px) {
  .twoam { padding: var(--s6) var(--s5) var(--s5); column-gap: var(--s3); }
  .twoam__cap { font-size: var(--t-body); }
}
/* on a phone there is no room for the mark between the letters (at 320px Ամստերդամ alone is
   wider than the gap), so the dimension is drawn the way a draughtsman draws it when the object
   is tight: below it, across the whole width, its ticks under the two AMs' outer edges, with the
   mark standing on it and the figure under it. The letters get the room back and grow. */
@media (max-width: 560px) {
  .twoam { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--s4); padding: var(--s5) var(--s4) var(--s4); }
  .twoam__end--from { grid-column: 1; grid-row: 1; }
  .twoam__end--to { grid-column: 2; grid-row: 1; }
  .twoam__am { font-size: var(--t-am-sm); }
  .twoam__span { grid-column: 1 / -1; grid-row: 2; grid-template-rows: var(--s7) auto auto; margin-top: var(--s4); }
  .twoam__mid .logo { height: var(--logo-h); }
  .twoam__place { font-size: var(--t-body); }
  .twoam__ms { font-size: var(--t-body); margin-top: var(--s2); }
  .twoam__end { gap: var(--s3); }
}
.twoam__where, .twoam__span > * { overflow-wrap: break-word; }
/* the home page's moment: the dimension is drawn once, from Armenia across to Amsterdam, and
   its figure is written under it as the line arrives. The drawing stands on the first screen,
   where the browser paints it before concept-a.js comes, so the moment is not left to the
   script's class (a drawing already seen stays as it was seen): it plays from the stylesheet,
   once, a beat after the first paint, from a first frame that hides only the line. The script's
   .is-pending holds that same frame when it does arrive first; reduced motion collapses it to
   the finished state (section 18), and so does paper (section 22) */
@keyframes span-run { from { clip-path: inset(-4px 100% -4px -4px); } to { clip-path: inset(-4px -4px -4px -4px); } }
@keyframes dim-in { from { opacity: 0; } to { opacity: 1; } }
.twoam__line { animation: span-run var(--dur-draw) var(--ease) var(--dur-2) 1 backwards; }
.twoam__ms, .twoam__mid .twoam__note { animation: dim-in var(--dur-2) var(--ease) calc(var(--dur-2) + var(--dur-draw) * 0.8) 1 backwards; }
.is-pending .twoam__line, .is-pending .twoam__ms, .is-pending .twoam__mid .twoam__note { animation-play-state: paused; }
/* section 18 cuts a duration, not a delay: the moment's beat would still hide the line */
@media (prefers-reduced-motion: reduce) { .twoam__line, .twoam__ms, .twoam__mid .twoam__note { animation: none; } }

/* Since the owner's review of 4 October 2026 (ADR 0051) the two AMs are not the first screen:
   they are the drawing of the home page's second band, on the dark sheet, a size down. The
   moment is the scroll's, as every other drawn moment is: the line waits for .is-pending and
   runs on .is-drawing, so it is drawn when it is seen and not before. */
@media (min-width: 561px) {
  .twoam--band { padding: var(--s6) var(--s6) var(--s5); }
  .twoam--band .twoam__am { font-size: var(--t-am-md); }
  .twoam--band .twoam__span { grid-template-rows: calc(var(--t-am-md) * 0.8) auto; }
  .twoam--band .twoam__cap { font-size: var(--t-body); }
}
.twoam--band { margin-inline: 0; margin-bottom: 0; }
.twoam--band .twoam__line, .twoam--band .twoam__ms, .twoam--band .twoam__mid .twoam__note { animation: none; }
.twoam--band.is-pending .twoam__line, .twoam--band.is-drawing .twoam__line { animation: span-run var(--dur-draw) var(--ease) 1 backwards; }
.twoam--band.is-pending .twoam__ms, .twoam--band.is-drawing .twoam__ms,
.twoam--band.is-pending .twoam__mid .twoam__note, .twoam--band.is-drawing .twoam__mid .twoam__note { animation: dim-in var(--dur-2) var(--ease) calc(var(--dur-draw) * 0.8) 1 backwards; }
.twoam--band.is-pending .twoam__line, .twoam--band.is-pending .twoam__ms, .twoam--band.is-pending .twoam__mid .twoam__note { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) { .twoam--band .twoam__line, .twoam--band .twoam__ms, .twoam--band .twoam__mid .twoam__note { animation: none; } }

/* What is different here: five points read at a glance — a head in the title size over one
   short line, each under an apricot rule, one row on a wide screen. The dash between head and
   line stays in the text for every reader that is not looking at the layout. */
.points { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--s6) var(--s5); }
.point { display: grid; align-content: start; gap: var(--s3); padding-top: var(--s4); border-top: var(--stroke) solid var(--accent); }
.point__head { font-size: var(--t-h3); line-height: 1.2; font-weight: var(--w-bold); color: var(--ink); }
.point__line { font-size: var(--t-body-2); color: var(--ink-2); }
@media (max-width: 1000px) { .points { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .points { grid-template-columns: minmax(0, 1fr); gap: var(--s5); } }

/* the form's own name, at the top of its plate */
.form__title { margin: 0 0 var(--s5); }

/* the same two AMs, small, in the title block of every sheet: the firm's mark beside its name */
.foot__twoam {
  display: flex;
  align-items: center;
  gap: var(--s2);
  width: 100%;
  max-width: 14rem;
  margin: 0;
  font-size: var(--t-h3);
  font-weight: var(--w-bold);
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--ink);
}
.foot__am--from { color: var(--accent-ink); }
.foot__span {
  flex: 1;
  height: var(--s3);
  border-inline: var(--stroke) solid var(--redline);
  background: linear-gradient(var(--redline), var(--redline)) center / 100% var(--stroke) no-repeat;
}

/* the three services, cloud first: a schedule of three rows read across — the name, what it
   is, where its price starts, the way in — not three cards. The first row is the lead one and
   says so in size and on a wash, the way a drawing's schedule marks the line it is about. */
.offers { border-top: var(--stroke) solid var(--ink); }
.offer {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 5fr) minmax(0, 3fr) minmax(max-content, 2fr);
  grid-template-areas: "name what from go" ". more . .";
  column-gap: var(--s5);
  align-items: baseline;
  padding: var(--s5) var(--s4);
  border-bottom: var(--hair) solid var(--line);
}
.offer--first { background: var(--accent-wash); padding-block: var(--s6); }
.offer__name { grid-area: name; font-size: var(--t-h3); line-height: 1.2; font-weight: var(--w-bold); }
.offer--first .offer__name { font-size: var(--t-h2); letter-spacing: var(--tr-h2); }
.offer__what { grid-area: what; margin: 0; color: var(--ink-2); max-width: 52ch; }
.offer__what::first-letter { text-transform: uppercase; }
.offer__from { grid-area: from; margin: 0; font-size: var(--t-body); font-weight: var(--w-mid); color: var(--ink); }
.offer__go { grid-area: go; justify-self: end; }
.offer__more { grid-area: more; margin: var(--s3) 0 0; font-size: var(--t-body-2); }
@media (max-width: 1000px) {
  .offer {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "name go" "what what" "from from" "more more";
    row-gap: var(--s3);
  }
  .offer__more { margin-top: 0; }
}
@media (max-width: 560px) {
  .offer { grid-template-columns: minmax(0, 1fr); grid-template-areas: "name" "what" "from" "more" "go"; }
  .offer__go { justify-self: start; margin-top: var(--s2); }
}
/* a key list that stays one column on a wide lane: its lines are sentences, not facts */
@media (min-width: 1000px) { .keylist--one { columns: auto; } }

/* the pool, drawn (ADR 0051): one limit dimensioned across the top in the annotation pen,
   ticks at both ends, its name knocked out of the line; under it the account's own split,
   three parts of one bar. On a phone the parts stack, each as long as its share. */
.pool { margin-inline: 0; margin-bottom: 0; display: grid; gap: var(--s4); }
.pool__dim { position: relative; margin: 0; text-align: center; font-family: var(--font-label); font-size: var(--t-mono); letter-spacing: var(--tr-caption); color: var(--redline-ink); }
.pool__dim::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; border-top: var(--stroke) solid var(--redline); }
.pool__dim::after { content: ""; position: absolute; left: 0; right: 0; top: calc(50% - var(--s2)); height: var(--s4); border-inline: var(--stroke) solid var(--redline); }
.pool__dim span { position: relative; padding-inline: var(--s3); background: var(--surface); }
.pool__split { display: flex; gap: var(--s1); }
.pool__seg {
  min-width: 0;
  padding: var(--s5) var(--s3);
  background: var(--accent-wash);
  border: var(--hair) solid var(--accent);
  border-radius: var(--radius);
  font-size: var(--t-body-2);
  line-height: 1.3;
  color: var(--ink);
  overflow-wrap: break-word;
}
.pool__seg--a { flex: 5; }
.pool__seg--b { flex: 3; }
.pool__seg--c { flex: 2; }
.pool__cap { font-size: var(--t-body-2); color: var(--ink-2); max-width: var(--measure); }
.pool__cap strong { color: var(--ink); }
@media (max-width: 560px) {
  .pool__split { flex-direction: column; align-items: flex-start; }
  .pool__seg { padding-block: var(--s3); }
  .pool__seg--a { width: 100%; }
  .pool__seg--b { width: 75%; }
  .pool__seg--c { width: 55%; }
}

/* the cloud next to five others: seven columns read across, so on a narrow screen the
   table scrolls in its own frame and the row's name stays pinned at the left edge. Our
   column stands on the apricot wash; nothing else in the table is coloured. */
.spec--rivals { min-width: 1080px; table-layout: fixed; }
.spec--rivals thead th { white-space: normal; }
.spec--rivals tbody th, .spec--rivals thead th:first-child { width: 16%; }
.spec--rivals th:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--surface);
  box-shadow: inset calc(-1 * var(--hair)) 0 0 var(--line);
}
.spec--rivals .is-ours { background: var(--accent-wash); color: var(--ink); }
.spec--rivals thead .is-ours { color: var(--accent-ink); }
.rivals__notes > * + * { margin-top: var(--s1); }
/* on a phone the table keeps its seven columns and its scroll, but narrower ones: the pinned
   name and our column fill the screen, and the first other cloud shows its edge — the cut is
   what says the table goes on */
@media (max-width: 640px) {
  .spec--rivals { min-width: 880px; }
  .spec--rivals tbody th, .spec--rivals thead th:first-child { width: 9rem; }
}
/* the pools' price, at the end of each pack's line, is the number a buyer came for */
.cards3 .callout [data-price-of] { font-family: var(--font-label); font-weight: var(--w-bold); font-size: var(--t-body); color: var(--accent-ink); }

/* ============================================================ 22. paper

   One print register for the whole stylesheet, and it has to stay one: there were two for
   a while — an early one beside the bands and a later one written when the grid band, the
   configurator, the quote and the folded answers arrived — and the next person to change
   what the site prints would have found one and missed the other. A printer drops grounds,
   so a band whose meaning sat in its ground says it again in ink; and a configurator prints
   the configuration rather than the empty controls that produced it. Checked as a real PDF
   of all three pages, not as a preview. It is the last block of the file on purpose: its
   rules win over the screen's by order, so nothing is written below it. */

@media print {
  /* the chrome goes */
  .top, .subnav { display: none; }
  .band { padding: var(--s6) 0; }

  /* Browsers drop backgrounds on paper, so the dark band turns itself into the paper
     register rather than trusting a printer setting: white ground, --ink type, hairline
     frame. Nothing on it is carried by colour alone once printed. The accent band needs
     no such rescue any more — it is already ink on a light ground. */
  .band--machine {
    /* the band goes back to paper the same way it went dark: by re-pointing the tokens.
       Every class inside it — the ones written today and the one written next month —
       follows, which is why no class is named here any more. */
    --paper:        var(--paper-ground);
    --surface:      var(--paper-surface);
    --ink:          var(--paper-ink);
    --ink-2:        var(--paper-ink-2);
    --ink-3:        var(--paper-ink-3);
    --line:         var(--paper-line);
    --line-2:       var(--paper-line-2);
    --grid:         var(--paper-grid);
    --accent-ink:   var(--paper-accent-ink);
    --signal:       var(--paper-signal);
    --redline:      var(--paper-redline);
    --redline-ink:  var(--paper-redline-ink);
    --redline-soft: var(--paper-redline-soft);
    background: var(--surface);
    color: var(--ink);
    border-block: var(--hair) solid var(--line);
  }
  /* the terminal panel used to be repainted here class by class, once inside the band
     and once outside it. The rules below, further down this block, cover both: a .term
     is a .term wherever it stands. */
  .band--accent { background-image: none; }

  /* every folded answer is open on paper: <details> is the page's only content store,
     and a printed page that hides half of itself is not the page. Two rules, because two
     generations of engine hide the closed half differently — a display:none slot in the
     older one, content-visibility on ::details-content in the newer. */
  details > *:not(summary) { display: block; }
  details::details-content { content-visibility: visible; block-size: auto; }
  .svc .a, .faq .a, .folds .a { display: block; }
  summary .chip--fold { display: none; }
  /* a price table runs over a sheet row by row instead of leaving its heading alone at
     the foot of the previous one */
  .spec { break-inside: auto; }
  .spec tr { break-inside: avoid; }
  .band__head, .band .cols { break-after: avoid; }

  /* the terminal panel is a dark panel wherever it stands, and three of the four on this
     site stand on paper rather than inside the dark band. It takes the paper register on
     its own account: light type on a ground the printer is free to drop is white on white.
     Section 18 says this for the ones inside .band--machine; this says it for the rest. */
  .term { background: var(--surface); border-color: var(--line); }
  .term pre, .term__list li, .term__list b { color: var(--ink); }
  .term__list .k { color: var(--accent-ink); }
  .term__list .d { color: var(--ink-2); }

  /* the configurator prints what it was set to. The slider is the one control whose
     state a printer cannot draw — its number is already beside the label in <output>,
     so the track goes and the figure stays. */
  .cfg .field input[type="range"] { display: none; }
  .cfg__opt input:checked + span { border-color: var(--ink); border-width: var(--stroke); background: transparent; color: var(--ink); }
  /* the option that was not chosen stays readable: --ink-3 is drawn rules and axis
     ticks, never running text, and on paper it measures 3.9:1. The chosen option is
     told apart by the weight of its border, not by greying the other one out. */
  .cfg__opt input:not(:checked) + span { color: var(--ink-2); border-color: var(--line); }
  /* .order__done is not a control — it is the receipt with the reference number, and it
     only ever stands after a real submit. Hiding it on paper took away the one thing on
     the page a buyer has a reason to print. The shelf's buttons, the line that explains
     them and the reset button do go: they are controls, and paper prints the configuration,
     not the way to change it. */
  .cfg__reset, .part__btn, .cfg__how { display: none; }
  /* the eight steps and the pile of jobs print as drawn: finished (the universal rule below
     stops every animation), the chain in ink so it survives a printer without colour */
  .journey__step::before { border-color: var(--ink); }
  .journey__step::after { border-color: var(--ink); }
  .part { display: block; border: 0; padding: 0; }
  .part__read { display: flex; justify-content: space-between; gap: var(--s2); }
  .part__n { min-width: 0; }
  .cfg__bay { border-color: transparent; }

  /* nothing is cut off by a scroll container that has no scrollbar on paper */
  .tablewrap { overflow: visible; }
  .spec--rivals { min-width: 0; table-layout: auto; font-size: var(--t-micro); }
  .spec--rivals th:first-child { position: static; box-shadow: none; }
  .twoam { break-inside: avoid; }
  .quote:not(.spec--stack) { min-width: 0; }

  /* a heading does not end a sheet, and a drawing does not straddle two */
  .h2, .h3, h1, h2, h3 { break-after: avoid; }
  table, figure, .plate, .callout { break-inside: avoid; }
  /* a paper illustration prints as the drawing it is; the dark one carries nothing the
     text does not and would print as a slab of toner, so it stays on screen */
  .band--machine .sheet { display: none; }
  .sheet img { -webkit-mask-image: none; mask-image: none; }
  /* a row of callouts is laid on a grid, and a grid item is not kept whole by the rule
     above: FIG. 07 on support.html printed a card's title on one sheet and its body on the
     next. The row is short, so the whole row moves to the next sheet instead. */
  .cards3 { break-inside: avoid; }
  /* the band's head row and its heading row are the heading: they go with what follows */
  .band__head, .band__head + .cols { break-after: avoid; }
  /* break-after on a heading does not reach past the grid cell it stands in: FIG. 03 on
     support.html printed its heading on one sheet and its lead on the next. The heading
     row is two short blocks, so it is kept whole instead. */
  .band__head + .cols { break-inside: avoid; }
  /* A picker's caption names the row of options under it and does not end a sheet. With
     every break around it forbidden, the engine broke the one inside it: «Pick a window»
     and «Pick a format» printed alone at the foot of a sheet. The break after the lead is
     the honest one, so it is allowed there, and the pickers leave the grid on paper — a
     grid item is not kept whole by break-inside. Checked in a real page.pdf, en/ru/hy. */
  .band .cols:has(+ .pick) { break-after: auto; }
  .pick > .caption { break-after: avoid; }
  /* a table's caption is its title: on pricing.html «FIG. 02 — Space and power» printed
     at the foot of a sheet with every row on the next */
  .spec > caption, .spec > thead { break-after: avoid; }
  /* a drawing caught mid-moment, or paused on its first frame waiting for its moment, prints
     finished: the animation is taken off. By importance, because the rule is universal and so
     has no specificity: every screen rule that names an animation or a transition on a class
     (.is-drawing .cables, .is-pending .cables, a control's transition) would outrank it */
  *, *::before, *::after { animation: none !important; transition: none !important; }
  /* a page has no bottom edge to ride: the quote's total stands in its row, and only there */
  .cfg .cfg__stick { display: none; }
  /* a door is a link on paper: the filled button's ground is dropped with every other ground,
     and its white words went with it, so it prints in ink inside a hairline, as the other does */
  .btn--primary { background: none; color: var(--ink); border: var(--hair) solid var(--ink); }
  /* The footer's title block prints as it stands, whole, on one sheet. Its rules are the
     block's ground showing through one-hair gaps, and a printer drops grounds, so the block
     asks for its own to be kept, drawn in --line-2, which survives on paper. It moves to the
     next sheet rather than split, and that needs a break allowed in front of it: the last
     band of every page ends in a .cols, whose break-after: avoid (above, for a band's head
     row) reached through the end of <main> and forbade the one break before the footer, so
     the engine cut the block after "Servers" instead. The note that exists for paper (UI-15
     print-note) takes its cell in the strip. */
  main > .band:last-child .inner > .cols:last-child { break-after: auto; }
  .foot { border-top: 0; padding: var(--s6) 0 0; break-inside: avoid; }
  .foot__block {
    background: var(--line-2); border-color: var(--line-2); break-inside: avoid;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  .foot__cell, .foot__facts { break-inside: avoid; }
  .foot__end li + li { border-left-color: var(--line-2); }
  .foot__end .foot__print { display: flex; }
}
