/* ============================================================================
   BIZSETUP.CSS — the Business Setup exhibit layer
   ============================================================================
   Geometry, palette and motion for the seven patterns in
   inc/bizsetup-visuals.php. Scoped entirely under `.cz-bz`: not one selector
   in this file can reach anything that was on the page before it.

   `!important` APPEARS THREE TIMES, 20 September 2026, and only inside the
   `@media (scripting: none)` block at the foot — a catch-all that has to beat
   its own pre-states, which are written on more specific selectors than a
   `… *` reset can use, so source order cannot win it. Nothing else in this
   file carries one.

   Loaded LAST, after cz-editorial, on the five Business Setup slugs only (and
   on any document that actually authors an exhibit — see cz_biz_enqueue()).

   ----------------------------------------------------------------------------
   HIS BRIEF, WHICH IS WHAT THIS FILE IS ANSWERING (R68)
   ----------------------------------------------------------------------------
   "Infographics should be vibrant, with animations, unique, creative, artistic
   and most importantly professional blending with the enviroment" ·
   "beautifull, vibrant, with animation, goof looking infographics" ·
   "Alligned, structured, placed properly" · "Proper allignment. Allignment and
   spacing issues are to be taken care off too. Clean ui/ux".

   Two of those pull against each other and the resolution is deliberate:
   VIBRANT comes from four saturated accents used on the marks that carry
   meaning, and BLENDING comes from every one of those accents being read out of
   main.css's own tokens or measured against them, from the type being the
   site's own scale, and from the vertical rhythm being the reading grid's own.
   Nothing here invents a look; it saturates the one that is already there.

   ----------------------------------------------------------------------------
   1. THE ALIGNMENT RULE — stated once, and every pattern obeys it
   ----------------------------------------------------------------------------
   THE LEFT EDGE. `margin-inline: 0` on `.cz-bz`, and every pattern's leftmost
   element sits at column start with no indent of its own. Nothing in this file
   sets a negative margin-left, a float or a hanging indent, so no exhibit can
   ever reintroduce the hang R5 forbids. Exhibits that want to be wide grow
   RIGHT, into the margin column.

   THE WIDTHS. Three, and all three are computed from the reading grid's own
   custom properties — `--cz-fig-measure` (74ch), `--cz-fig-full` and
   `--cz-read-gap` — which placement.css declares on `.cz-reading__body` and
   redefines per breakpoint. So when that grid changes, these follow, and
   nothing here goes stale. Unlike the SVG devices next door these patterns
   REFLOW, so they take the arithmetic widths with NO minimum-width floor: there
   is no drawing to hold open, nothing scrolls inside itself, and horizontal
   overflow is zero by construction rather than by measurement.

   THE INTERNAL GRID. One gutter token, `--bz-gap`, and one row token,
   `--bz-row`, for every pattern. A label column is `--bz-key` wide wherever a
   pattern has one — the `routes` criterion column, the `durations` stage
   column, the `threshold` band column and the `decides` gate column all break
   at the same place, and the figure beside each sits in the next column rather
   than flush right. `buildup` is the one exception and it is a deliberate one:
   a column of money aligns on its digits, so its figures ARE flush right,
   against the same right edge as the cost track above them.

   THE VERTICAL RHYTHM. `margin-block: clamp(30px, 3vw, 46px) clamp(18px,
   1.8vw, 26px)` — the same pair devices-variants.css:203 uses, so an exhibit
   from this file sits in exactly the rhythm an exhibit from that one does, and
   a page carrying both has one spacing system and not two. Internal spacing
   steps off `--bz-row` and never off an ad-hoc pixel value.

   MEASURED AT 375, 768 AND 1440. Every breakpoint below is BOUNDED at both
   ends where it needs to be: reading.css:70 records what an open-ended
   `max-width: 1400px` did to a 375px phone, and this file does not repeat it.

   ----------------------------------------------------------------------------
   2. THE PALETTE, WITH EVERY RATIO MEASURED
   ----------------------------------------------------------------------------
   Four categorical accents. FOUR, not six: 23-EXHIBIT §4 collects five
   institutional limits and four is the lowest of them (UK Government Analysis
   Function), so this cannot drift into a rainbow. Ratios below are WCAG 2.x
   computed against the three grounds these exhibits actually sit on.

     TOKEN        HEX        on #fff   on #f3f5f7   white text on it
     --bz-c1      #0b5fa5      6.57       6.02          6.57
     --bz-c2      #0c6f78      5.90       5.40          5.90
     --bz-c3      #856527      5.40       4.94          5.40   (= --cz-gold-ink)
     --bz-c4      #7b3f62      7.69       7.04          7.69
     --bz-quiet   #5b6570      5.93       5.43            --    (= --cz-mid)
     --bz-rule    #8b949d      3.08       2.82            --
     --bz-ink     #14181c     17.84      16.32            --    (= --cz-text)

   So every accent clears 4.5:1 as a word and as a thin mark, every accent
   carries white type at 4.5:1 when it is a filled area, and --bz-rule clears
   the 3:1 floor for a graphical object that carries meaning. --bz-c3 IS the
   site's gold at ink weight, which is how the layer stays in the brand: the
   raw --cz-gold (#c7a36b) measures 2.36:1 on white and appears in this file
   only on dark grounds, where it is 8.57:1.

   ADJACENCY, AND THE ONE PLACE THIS PALETTE IS NOT SELF-SUFFICIENT. Measured
   accent against accent the ratios are 1.09:1 to 1.56:1 — nowhere near the 3:1
   two touching marks need. So no two accent fills ever touch: the stacked track
   in `buildup` puts a 2px paper border inside every segment but the last, and
   every segment, column, band and route is DIRECTLY LABELLED in text. Colour is
   never the only means of conveying information (WCAG SC 1.4.1), and there is
   not one colour key in this file that direct labelling could have done
   instead — 23-EXHIBIT §5 files that substitution as an accessibility failure,
   not an inelegance.

   THE DARK TWINS are declared and used only where an exhibit lands on an ink
   ground: #5aa9ef (8.07:1 on #050607), #4fc3d0 (9.70:1), --cz-gold (8.57:1),
   #d493b4 (8.34:1).

   THE FOCUS PALETTE, and exactly where it applies. In `routes`, `::pick` names
   the route the page is arguing for and every OTHER column drops to --bz-quiet:
   one column in colour, the rest grey. That move has a documented name and a
   documented reason ("People look first at the highest-contrast, most saturated
   colour in your chart… If everything is important and emphasized, nothing
   is"), and it is the cheapest route from busy to professional.

   In the other six patterns a `*` on a row label EMPHASISES that row — its
   heading and its figure take the accent — and the other rows keep their own
   accents, because there the four accents ARE the categories and quieting them
   would throw the encoding away.

   ----------------------------------------------------------------------------
   3. R51 — NOTHING IS BOXED, WITH ONE ARGUED EXCEPTION
   ----------------------------------------------------------------------------
   No card, no border, no radius, no shadow and no tinted field behind an
   exhibit. Structure is hairlines, alignment and whitespace. Where
   cz_wrap_tables() adds `.cz-tablewrap` inside `routes`, that wrapper is
   UNBOXED rather than fought: it keeps its focus ring and its scroll behaviour
   and stops being a panel.

   The exception is the `threshold` band tint. A band there is the interval
   itself — a value, the way a bar is a length — not a container around a value.
   It measures 1.14:1 against white, so it can never be the only cue: every band
   also carries its range and its consequence as text.

   ----------------------------------------------------------------------------
   4. MOTION (R16, and his "with animations")
   ----------------------------------------------------------------------------
   THE CONTRACT, and it is the one devices.css already established, reused
   exactly so the two engines cannot disagree:

     - the pre-state exists ONLY under `.cz-bz[data-reveal]:not(.visible)`.
       cz_add_reveal_hooks() puts `data-reveal` on every <figure>, and main.js
       adds `.visible` when the figure intersects — or IMMEDIATELY, to
       everything, when the reader prefers reduced motion or the browser has no
       IntersectionObserver. So the finished exhibit is the default and the
       animation is the exception, never the other way round;
     - only `transform`, `opacity` and `stroke-dashoffset` are animated. No
       height, no width, no margin, no top: zero layout cost and zero CLS;
     - NOTHING BOUNCES. The easings are --cz-ease-out (.16,1,.3,1) and
       --cz-ease (.2,.7,.2,1). Neither overshoots. There is no keyframe
       animation in this file at all, so nothing loops and nothing spins;
     - `@media (prefers-reduced-motion: reduce)` neutralises every pre-state and
       every transition, leaving the finished, fully visible exhibit. `@media
       print` does the same, because a printed page never gets an observer.

   THE THREE BEATS, so the sequence is legible rather than decorative:
     A. GROUND      the axis, spine, stem or track rule draws (stroke-dashoffset
                    over a normalised pathLength, or scaleX from the left edge).
     B. DATA        segments, bars, bands, rows and cells arrive in reading
                    order, 60-110ms apart, from 6-8px off their resting place.
     C. THE CLAIM   the total, the threshold line and the focus row land last.
   ============================================================================ */


/* ------------------------------------------------------------
   TOKENS — scoped to the layer, never added to :root
   ------------------------------------------------------------
   main.css:1 states the rule outright: tokens are declared once, there, and
   nowhere else, because nine competing :root blocks once shipped two golds and
   two inks on every page. These are the exhibit layer's own values and they
   belong to the exhibit layer. Everything that CAN be read from the site's
   tokens is read from them, with a literal fallback so a renamed token
   degrades to a measured colour rather than to `unset`.
   ------------------------------------------------------------ */
.cz-bz {
  /* Categorical four. Measured ratios are in section 2 of the header. */
  --bz-c1: #0b5fa5;
  --bz-c2: #0c6f78;
  --bz-c3: var(--cz-gold-ink, #856527);
  --bz-c4: #7b3f62;

  /* The same four on an ink ground, where the light values fail. */
  --bz-c1-dk: #5aa9ef;
  --bz-c2-dk: #4fc3d0;
  --bz-c3-dk: var(--cz-gold, #c7a36b);
  --bz-c4-dk: #d493b4;

  /* Ground and ink, from the site's own tokens. */
  --bz-ink: var(--cz-text, #14181c);
  --bz-quiet: var(--cz-mid, #5b6570);
  --bz-paper: var(--cz-paper, #fff);

  /* Two line weights, and they are not interchangeable. --bz-rule carries
     meaning and clears 3:1; --bz-hair is structure only and never the sole
     cue for anything. */
  --bz-rule: #8b949d;
  --bz-hair: var(--cz-line, rgba(8, 10, 13, .11));

  /* The house gridline, and it is not negotiable. 23-EXHIBIT §1, from the real
     Economist styleguide: "Horizontal gridlines only. No verticals, no minors.
     Grey #dcdbd8." Used on the ticks and nowhere else in this file, because
     these seven shapes carry ticks rather than a gridded field. */
  --bz-grid: #dcdbd8;

  /* The current accent. Every pattern sets this on a row or a group and the
     marks inside read it, which is how one rule paints a swatch, a bar, a
     dial and a stem without four copies of each. */
  --bz-hue: var(--bz-c1);

  /* Spacing. One gutter, one row step, one label column — section 1. */
  --bz-gap: clamp(12px, 1.2vw, 18px);
  --bz-row: clamp(10px, 1vw, 14px);
  --bz-key: clamp(150px, 15vw, 240px);

  /* THE MEASURE OF A SECONDARY NOTE, and it is a correction.

     Measured at 1440 on 20 September 2026, with 1ch of this face at 13px coming
     out at 8.35px: a fork's detail line ran 717px, which is 86 characters, and a
     threshold band's consequence ran 674px, which is 81. The comfortable band is
     45 to 75 and a note nobody finishes is information the exhibit did not
     deliver. 66ch is inside the band by construction — it is the same count
     whatever the type size, which is why the unit is ch and not px, and the arm
     details at 15px cap at 636px while the 13px ones cap at 551px. It is a CAP,
     so a column narrower than that simply ignores it. */
  --bz-note: 66ch;

  /* Type. The 12px floor is R7 and it is a floor, not a size. */
  --bz-t-unit: 12px;
  --bz-t-note: 13px;
  --bz-t-body: 15px;
  --bz-t-head: 16px;

  /* THE DATUM STEP, AND IT IS A CORRECTION MADE 20 SEPTEMBER 2026.
     --bz-t-fig WAS 15px, WHICH IS --bz-t-body. Measured on
     /business-setup-in-dubai/ at 1440: every figure in every exhibit rendered
     at 15px/700 and every label beside it at 15px/600, so the number and its
     own name were the same size and were separated by one weight step and a
     hue. That is what "timid type" looks like from the inside — there is no
     hierarchy to read, the eye has nowhere to land, and a drawing reads as a
     styled list. His words on seeing it: "could have been more artistic,
     aesthetic, creative… and overall better and professional."

     17 to 20px against a 15px label is a ratio of 1.13 to 1.33. A real step,
     and deliberately short of the 2x that turns an exhibit into a poster:
     23-EXHIBIT §1 records the Economist's own headline-to-subtitle ratio as
     9.5:8, "a subtle step, not the 2x that secondary blogs claim", and this is
     that judgement applied one level down. The three classes it reaches are the
     three datums in this file — buildup's money column, durations' stage
     duration and threshold's band range — and every one of them already carries
     tabular figures, so a column still aligns on its digits at the larger size.
     `.cz-bz__colv` is NOT in the set and stays at 12px: it is a value under a
     small-multiple bar, where the bar is the datum and the number annotates it. */
  --bz-t-fig: clamp(17px, .38vw + 15px, 20px);

  /* Motion.
     --bz-step WAS 80ms AND IS NOW 64ms, AND EVERY DELAY THAT USES IT NOW CLAMPS
     THE INDEX AT EIGHT. Measured: the ten-row comparison on
     /business-setup-in-uae/ finished its entrance 1.32s after it started, which
     is long enough for a reader to arrive at row four and watch the rest of the
     table catch up. `min(var(--i, 0), 8)` caps the stagger window at 512ms —
     inside the 200-600ms a reveal has to live in — and everything past the
     eighth row lands with the eighth. Rows that arrive together are not a
     compromise here: they are the correct reading, because after eight the
     stagger has said everything it has to say. */
  --bz-in: .52s;
  --bz-step: 64ms;

  display: block;

  /* THE EXHIBIT IS ITS OWN QUERY CONTAINER, and that is the one thing a media
     query could not do here. These patterns come in three widths that a
     viewport cannot tell apart: at 1440 a `measure` exhibit is 713px and a
     `step` exhibit beside it is 759px, and the row layout that is right at 759
     is wrong at 713 — measured, on /business-setup-in-dubai/, where a
     177-character consequence went from two lines to four when it was moved
     into a third track that had 283px to give it. Asking the EXHIBIT its width
     instead of the window gets both cases right with one rule, and it keeps
     working when the rail form takes the margin column and every exhibit on the
     page narrows at once. Used once, in the block headed THE THREE-PART ROW.

     Safe on all three widths because every one of them is declared explicitly
     (see THE THREE WIDTHS): inline-size containment means the box does not look
     at its contents to size itself, and none of these boxes ever did.
     Unsupported browsers simply never match the query and keep the two-line
     row, which is the fallback either way. */
  container-type: inline-size;
  container-name: bz;

  margin-inline: 0;                 /* R5 — one left edge, always. */
  margin-block: clamp(30px, 3vw, 46px) clamp(18px, 1.8vw, 26px);
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  color: var(--bz-ink);
  font-family: var(--sans, "Overpass", "Segoe UI", Arial, sans-serif);
  font-size: var(--bz-t-body);
  line-height: 1.45;
}

/* Belt and braces on the left edge: placement.css pins .cz-fig, editorial.css
   pins its own, and this pins these — under both the body and the prose, so a
   template that nests differently cannot reintroduce a hang. */
.cz-reading__body .cz-bz,
.cz-prose .cz-bz {
  margin-left: 0;
  margin-right: 0;
  float: none;
}

/* The accent slots. Set --bz-hue and everything downstream follows. */
.cz-bz__c--1 { --bz-hue: var(--bz-c1); }
.cz-bz__c--2 { --bz-hue: var(--bz-c2); }
.cz-bz__c--3 { --bz-hue: var(--bz-c3); }
.cz-bz__c--4 { --bz-hue: var(--bz-c4); }

/* ------------------------------------------------------------
   THE ORDERED RAMP — added 20 September 2026, and it is a correction
   ------------------------------------------------------------
   23-EXHIBIT §4 is unambiguous: "Chronological categories take a light-to-dark
   ramp of ONE hue, not different hues."

   Two of the seven kinds are ordered and both were cycling the categorical four:
   `durations` is the FT family "Change over time" by its own declaration in
   cz_biz_kinds(), and `buildup` lays charges out "in the order a founder meets
   them". So four sequential stages drew blue, teal, gold and plum — four
   unrelated hues saying the four stages are four unrelated things, which is the
   opposite of what a sequence means, and with five stages the fifth repeated the
   first. It is also the single clearest difference between a drawing that looks
   designed and one that looks generated.

   FIVE STEPS, BUILT ON LIGHTNESS, which is the load-bearing channel — not
   saturation. The hue bends slightly across the run so a "monochromatic" ramp
   keeps its discriminability (§4, "building a ramp from one hue"). Measured on
   paper, because a ramp step is used as a MARK and as TYPE in this file:

     --bz-s1  #6d93b4   3.06:1   mark only
     --bz-s2  #3f7aa8   4.07:1   mark only
     --bz-s3  #1f6698   5.52:1   mark and type
     --bz-s4  #124f7e   7.94:1   mark and type
     --bz-s5  #0d3557  11.31:1   mark and type

   Steps 1 and 2 clear the 3:1 a graphical object needs and NOT the 4.5:1 type
   needs, so the two kinds that use this ramp keep their labels on --bz-ink and
   spend the ramp on the segment, the bar and the swatch. The figure beside a
   step-1 row would fail, so `.cz-bz--buildup .cz-bz__figure` and `.cz-bz__dur`
   stay on ink and take the accent only on the focus row, where the hue is
   --bz-hue and not a ramp step.
   ------------------------------------------------------------ */
.cz-bz {
  --bz-s1: #6d93b4;
  --bz-s2: #3f7aa8;
  --bz-s3: #1f6698;
  --bz-s4: #124f7e;
  --bz-s5: #0d3557;
}

.cz-bz__s--1 { --bz-hue: var(--bz-s1); }
.cz-bz__s--2 { --bz-hue: var(--bz-s2); }
.cz-bz__s--3 { --bz-hue: var(--bz-s3); }
.cz-bz__s--4 { --bz-hue: var(--bz-s4); }
.cz-bz__s--5 { --bz-hue: var(--bz-s5); }

/* A ramp row's own words stay on ink: steps 1 and 2 are under 4.5:1. The ramp
   is on the mark, which is where a sequence is read anyway. */
.cz-bz--durations .cz-bz__stage:not(.is-focus) .cz-bz__stageh,
.cz-bz--durations .cz-bz__stage:not(.is-focus) .cz-bz__dur,
.cz-bz--buildup .cz-bz__item:not(.is-focus) .cz-bz__name,
.cz-bz--buildup .cz-bz__item:not(.is-focus) .cz-bz__figure {
  color: var(--bz-ink);
}

/* THE FOCUS PALETTE, in `routes`, where a whole COLUMN is quieted rather than a
   row emphasised. The quieting is done on the custom property, because custom
   properties resolve by inheritance rather than by specificity, so re-assigning
   --bz-hue on the element that carries the slot beats the slot on that element
   and everything inside it.

   NAMED ELEMENT BY ELEMENT AND NOT AS `:not(.is-focus)` UNDER THE ROOT, and
   this is the bug that catches every first draft of this rule: a descendant
   selector also matches the CHILDREN of the focus column — `.cz-bz__cellv`,
   `.cz-bz__dial` — none of which carries `.is-focus`, all of which would then
   re-declare --bz-hue as quiet and grey out the one column the author asked to
   stand out. Only the two elements that carry a slot are addressed.

   In the other six patterns a `*` on a row label EMPHASISES that row (its
   heading and figure take the accent) and the rest keep their own categorical
   accents, because there the four accents are the categories. Quieting them
   would throw away the encoding. */
.cz-bz.has-focus .cz-bz__route-h:not(.is-focus),
.cz-bz.has-focus .cz-bz__cell:not(.is-focus) {
  --bz-hue: var(--bz-quiet);
}


/* ------------------------------------------------------------
   THE THREE WIDTHS
   ------------------------------------------------------------
   Every one grows RIGHT from the same left edge. The values are the reading
   grid's own custom properties, declared in placement.css:124 on
   `.cz-reading__body` and redefined there per breakpoint: below 1401px
   --cz-fig-full resolves to 100% and below 1001px --cz-fig-measure does too,
   which is correct — at those widths there is no margin column to grow into.

   NO MINIMUM-WIDTH FLOOR, and that is the difference from
   devices-variants.css:246. Those three widths carry `max(…, 752px)` because an
   SVG drawing has labels that stop being 12px if the box shrinks. Nothing here
   is drawn in SVG text, so there is nothing to hold open and a floor would
   only create the overflow it was meant to prevent.

   `width` AND `max-width`, not max-width alone. A block element is as wide as
   its containing block whatever its max-width says; declaring only the cap is
   what once left every device at the prose column's width and scrolling 201px
   inside itself at 1440.
   ------------------------------------------------------------ */
.cz-bz--w-measure {
  width: var(--cz-fig-measure, 74ch);
  max-width: 100%;
}
.cz-bz--w-step {
  width: calc(var(--cz-fig-measure, 74ch) + var(--cz-read-gap, 40px));
  max-width: var(--cz-fig-full, 100%);
}
.cz-bz--w-bleed {
  width: var(--cz-fig-full, 100%);
  max-width: var(--cz-fig-full, 100%);
}

/* The one place a keyboard reaches an exhibit: the scroll region
   cz_wrap_tables() puts inside `routes`. Unboxed, not removed — it keeps its
   focus ring and its scrollability and stops being a panel (R51). */
.cz-bz .cz-tablewrap {
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  overflow: visible;
}

/* ------------------------------------------------------------
   THE PROSE RESET — and every line of it is a measured specificity match
   ------------------------------------------------------------
   These exhibits render inside `.cz-prose.cz-prose--article`, which styles
   lists and paragraphs for READING. The lists an exhibit is built from are
   structures, not prose lists, and four of those rules reach into them. Each
   line below is written to the exact score of the rule it has to clear, and
   bizsetup.css prints after article.css and reading.css, so an equal score
   wins on source order:

     reading.css:389  .cz-prose ul, .cz-prose ol        (0,1,1)  padding-left 22px, colour
     reading.css:391  .cz-prose li + li                 (0,1,2)  margin-top .5em
     reading.css:393  .cz-prose ul li                   (0,1,2)  position, padding-left 24px
     reading.css:397  .cz-prose ul li::before           (0,1,3)  A GOLD DOT
     article.css:1182 .cz-prose--article ul li          (0,1,2)  padding-left 27px
     article.css:1188 .cz-prose--article li + li        (0,1,2)  margin-top .62em

   The gold dot is the one that matters most: without the (0,1,3) line, every
   gate in `decides` would carry a bullet it was never given, and a bullet
   beside a stem reads as a second stem.

   `:is()` takes the score of its most specific argument, which for a list of
   bare type selectors is one type — so `.cz-bz :is(ol, ul) li::before` scores
   (0,1,3) exactly, and not more.

   `padding-left`, not `padding` — a shorthand here would wipe the
   padding-bottom that gives every row its hairline its clearance.
   ------------------------------------------------------------ */
.cz-bz :is(p, ol, ul, dl, dt, dd) {
  margin: 0;
  padding: 0;
}

.cz-bz :is(ol, ul) {
  color: inherit;
  list-style: none;
}

.cz-bz :is(ol, ul) li,
.cz-bz li + li {
  position: static;
  margin-top: 0;
  padding-left: 0;
}

.cz-bz :is(ol, ul) li::before,
.cz-bz :is(ol, ul) li::marker {
  display: none;
  background: none;
  content: none;
}


/* ------------------------------------------------------------
   THE UNIT STRIP — not a caption (R42, R3.9), and now the family mark
   ------------------------------------------------------------
   It names the measure, which is the one thing an exhibit cannot leave to the
   prose without becoming ambiguous. Left-flush to the exhibit's own left edge,
   which is The Economist's rule for every piece of chart furniture, and it is
   also section 1's rule here.

   IT IS ALSO, AS OF 20 SEPTEMBER 2026, THE ONE MARK THAT MAKES SEVEN SHAPES
   READ AS ONE FAMILY — and it is not invented, it is the mark this site already
   uses twice. `.cz-masthead__kicker::before` (article.css:1305) and
   `.cz-footer__lead-kicker::before` (main.css:6562) are both an uppercase gold
   label with a short rule in currentColor set inline before it. That is the
   house kicker, and it is also, independently, The Economist's own furniture
   grammar: a short tag at the top left, on the rule, above everything else
   (23-EXHIBIT §1). Adopting it costs one pseudo-element and answers the whole
   of "professional, blending with the site" — an exhibit now announces itself
   in the site's own voice rather than in a grey caption nobody reads.

   THE BOTTOM HAIRLINE IS GONE, deliberately. With a tag on it the strip no
   longer needs a rule to separate it from the data, and neither kicker on the
   site carries one. It was also a full-width horizontal line sitting directly
   above the exhibit's own hairlines and competing with them — the exact ink
   Tufte files under chartjunk. The space it used to hold is now held by space.

   GOLD, AND WHY IT IS ALLOWED TO BE. --bz-c3 is --cz-gold-ink (#856527), which
   measures 5.40:1 on white and 4.94:1 on #f3f5f7 at this size and weight, and
   8.57:1 in its dark twin. R17 gives gold to emphasis and this is emphasis, not
   an action and not a fill. The named literal is --bz-c3 rather than --bz-hue
   because --bz-hue is the DATA accent: in `routes` it is reassigned per column,
   and furniture that changes colour with the data is furniture pretending to be
   data (The Economist keeps its own red off every series for the same reason).
   ------------------------------------------------------------ */
/* (0,2,0), because this is a `<p>`: it has to clear `.cz-prose p { color }` at
   (0,1,1) and the paragraph reset above at (0,1,1). Every `<p>` component in
   this file carries the doubled scope for the same reason. */
.cz-bz .cz-bz__unit {
  display: flex;
  /* nowrap, AND IT IS THE WHOLE DIFFERENCE BETWEEN THIS AND THE MASTHEAD.
     `.cz-masthead__kicker` labels two or three words and never wraps; a unit
     strip is a phrase, and at 375px "typical duration, complete documentation
     assumed" is three lines. Allowed to wrap as a FLEX LINE, the text went to
     the second flex line and left the rule sitting alone above it — seen at
     375px on /business-setup-in-dubai/. Held on one flex line, the text item
     shrinks and wraps inside itself instead, so the rule hangs to the left of
     the label and every line of the label shares one left edge. That is the
     alignment rule in section 1, applied to the one piece of furniture that
     sits outside the exhibit's grid. */
  flex-wrap: nowrap;
  align-items: flex-start;
  gap: 11px;
  margin: 0 0 calc(var(--bz-row) * 1.5);
  padding: 0;
  color: var(--bz-c3);
  font-size: var(--bz-t-unit);
  font-weight: 800;
  letter-spacing: .13em;
  line-height: 1.3;
  text-transform: uppercase;
}

/* 26px x 2px in currentColor, the same mark and the same arithmetic as
   `.cz-masthead__kicker::before`. `flex: none` so a shrinking label can never
   squeeze the rule to nothing, and the top margin centres it on the FIRST line
   — .58em of a 1.3 line box, less the rule's own weight — rather than on the
   middle of a label that may be three lines tall. `align-items: center` is what
   the masthead can afford and this cannot. */
.cz-bz .cz-bz__unit::before {
  flex: none;
  width: 26px;
  height: 2px;
  margin-top: .58em;
  background: currentColor;
  content: "";
}

/* Shared type primitives. Every pattern's heading, figure and note come from
   here, which is the other half of "seven shapes, one system". */
.cz-bz__name,
.cz-bz__steph,
.cz-bz__stageh,
.cz-bz__bandh,
.cz-bz__multh,
.cz-bz__gateh,
.cz-bz__crit {
  color: var(--bz-ink);
  font-size: var(--bz-t-body);
  font-weight: 600;
  line-height: 1.32;
  /* A heading in a narrow label column wraps, and a wrap that leaves one word
     alone on the second line is the single most visible misalignment in an
     exhibit. `balance` evens the lines; where it is not supported the heading
     wraps exactly as it does today. */
  text-wrap: balance;
}

.cz-bz__figure,
.cz-bz__dur,
.cz-bz__bandr,
.cz-bz__colv,
.cz-bz__total-v,
.cz-bz__linev {
  /* Tabular figures so a column of money or days aligns on its digits. */
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

.cz-bz__by,
.cz-bz__stepd,
.cz-bz__stagew,
.cz-bz__bandw,
.cz-bz__gatew,
.cz-bz__keyname {
  color: var(--bz-quiet);
  font-size: var(--bz-t-note);
  font-weight: 400;
  line-height: 1.42;
}

/* THE MEASURE CAP ON THE FOUR PROSE NOTES. Not on --keyname, which is a legend
   label and is one or two words by construction. See --bz-note for the
   measurement this corrects. */
.cz-bz__by,
.cz-bz__stepd,
.cz-bz__stagew,
.cz-bz__bandw,
.cz-bz__gatew {
  max-width: var(--bz-note);
  text-wrap: pretty;
}

/* A visually hidden label, for the one table header that has no visible text.
   Not `display: none`: that would take it out of the accessibility tree, which
   is the whole reason it exists. */
.cz-bz__vh {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  border: 0;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* The swatch that ties a legend line to its mark. 10px is under the 12px type
   floor and is allowed to be: R7 governs TEXT, and this carries no text — it is
   a graphical object, and at 10px against paper its accent clears the 3:1 that
   governs those. */
.cz-bz__swatch {
  flex: 0 0 auto;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  background: var(--bz-hue);
}


/* ============================================================
   1. BUILDUP — a cost build-up
   ============================================================
   A stacked track, then a directly-labelled legend, then the authored total
   under a rule. Proportional ink holds: the segments sum to the bar.
   ============================================================ */
.cz-bz--buildup .cz-bz__track {
  display: flex;
  align-items: stretch;
  width: 100%;
  height: 22px;
  margin: 0 0 calc(var(--bz-row) * 1.4);
  overflow: hidden;
}

.cz-bz--buildup .cz-bz__seg {
  flex: 0 0 auto;
  width: var(--w, 0%);
  min-width: 6px;

  /* THE 2px PAPER GAP IS LOAD-BEARING, NOT STYLING. Measured accent against
     accent the ratios are 1.09:1 to 1.56:1, nowhere near the 3:1 two touching
     marks need, so two accent fills may never meet — paper between them is what
     makes the boundary visible at all (header section 2).

     It is a BORDER and not a flex `gap`, and that is the R5 fix rather than a
     preference: `gap: 2px` with widths summing to 100% makes the track
     100% + 2px x (n-1) wide, which overflows and then gets clipped by the
     `overflow: hidden` above — so the last segment silently loses a slice of
     its own value. With the global `box-sizing: border-box` a right border is
     taken from INSIDE the segment, the widths still sum to exactly 100%, and
     nothing overflows anything. */
  border-right: 2px solid var(--bz-paper);

  /* The flat fill first, so an engine that cannot parse color-mix() still
     paints the segment. A dropped `background` here is not a lost gradient, it
     is an invisible bar. */
  background: var(--bz-hue);

  /* Vibrant, and still one hue per segment: a light-to-dark sweep across the
     fill reads as light falling on it rather than as a second colour. "Warm
     source against cool ground" is 17-ART-DIRECTION's grammar, and this is the
     same move at the scale of a bar. */
  background:
    linear-gradient(
      100deg,
      color-mix(in oklab, var(--bz-hue) 88%, #fff) 0%,
      var(--bz-hue) 58%,
      color-mix(in oklab, var(--bz-hue) 86%, #000) 100%
    );
  transform-origin: left center;
}

.cz-bz--buildup .cz-bz__seg:last-child {
  border-right: 0;
}

.cz-bz--buildup .cz-bz__legend {
  display: grid;
  gap: var(--bz-row);
}

.cz-bz--buildup .cz-bz__item {
  display: grid;
  grid-template-columns: 10px minmax(0, 1fr) auto;
  align-items: baseline;
  column-gap: var(--bz-gap);
  row-gap: 2px;
  padding-bottom: var(--bz-row);
  border-bottom: 1px solid var(--bz-hair);
}

.cz-bz--buildup .cz-bz__swatch {
  /* Lifted onto the first text baseline rather than centred in a row whose
     height is decided by a wrapping label. */
  transform: translateY(-1px);
}

.cz-bz--buildup .cz-bz__figure {
  color: var(--bz-ink);
  font-size: var(--bz-t-fig);
  font-weight: 700;
  text-align: right;
  white-space: nowrap;
}

.cz-bz--buildup .cz-bz__by {
  grid-column: 2 / 4;
}

.cz-bz--buildup .cz-bz__item.is-focus .cz-bz__name,
.cz-bz--buildup .cz-bz__item.is-focus .cz-bz__figure {
  color: var(--bz-hue);
}

/* The last charge keeps no hairline: the bracket below it is already a rule,
   and two horizontal lines seven pixels apart read as a mistake. */
.cz-bz--buildup .cz-bz__item:last-child {
  padding-bottom: 0;
  border-bottom: 0;
}

/* THE BRACKET that closes the charges into the sum. Its two ends turn UP into
   the column above it, which is what makes it a sum-of-parts mark rather than a
   divider. The box height is pinned so the long run's stroke is not distorted
   by the stretch — see cz_biz_bracket(). */
.cz-bz__bracket {
  display: block;
  width: 100%;
  height: 12px;
  margin-top: calc(var(--bz-row) * 1.4);
}

.cz-bz__bracket-path {
  stroke: var(--bz-ink);
  stroke-dashoffset: 0;
}

/* THE TOTAL. The claim the exhibit is making, so it arrives last and it is the
   only thing here at display weight. */
.cz-bz .cz-bz__total {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--bz-gap);
  margin-top: calc(var(--bz-row) * .7);
  padding-top: 0;
}

.cz-bz__total-k {
  color: var(--bz-quiet);
  font-size: var(--bz-t-unit);
  font-weight: 700;
  letter-spacing: .085em;
  text-transform: uppercase;
}

.cz-bz__total-v {
  color: var(--bz-ink);
  font-size: clamp(20px, 2.1vw, 27px);
  font-weight: 700;
  letter-spacing: -.01em;
  line-height: 1.05;
}


/* ============================================================
   2. ROUTES — two or three routes on the same rows
   ============================================================ */
.cz-bz--routes .cz-bz__grid {
  width: 100%;
  border-collapse: collapse;
  border-spacing: 0;
  /* R51: the table is not a panel. No outer border, no zebra fill, no header
     tint — the structure is one hairline per row and the column heads. */
  background: none;
  /* Declared, not inherited: `.cz-prose--article table` (0,1,1) sets 14.8px /
     1.45 for a reading table and `.cz-prose--article` sets 1.7 above that.
     (0,2,0) clears both. */
  font-size: var(--bz-t-body);
  letter-spacing: normal;
  line-height: 1.45;
}

/* EVERY SELECTOR BELOW GOES THROUGH `.cz-bz__grid`, and it is not a stylistic
   choice. `.cz-bz--routes .cz-bz__grid th` scores (0,2,1) because of the type
   selector, so a cell rule written as `.cz-bz--routes .cz-bz__route-h` scores
   (0,2,0) and LOSES to it — the 2px accent border under a column head would
   silently stay a 1px hairline. Adding `.cz-bz__grid` takes every cell rule to
   (0,3,0) and the cascade reads the way it looks like it reads. */
.cz-bz--routes .cz-bz__grid th,
.cz-bz--routes .cz-bz__grid td {
  /* .85 of the row step, not the whole of it. A ten-row comparison is the
     longest thing this file draws — 913px at 1440 before this — and the row
     rhythm is the only part of that a stylesheet is allowed to shorten, because
     the rows themselves are the author's data and none of them may go. */
  padding: calc(var(--bz-row) * .85) var(--bz-gap) calc(var(--bz-row) * .85) 0;
  border: 0;
  border-bottom: 1px solid var(--bz-hair);
  background: none;
  text-align: left;
  vertical-align: top;

  /* THE SIX PROPERTIES `.cz-prose--article th` WOULD OTHERWISE SET, and they
     have to be named rather than left alone. That rule turns every `th` in the
     reading column into a 13px, weight-800, uppercase, .16em-tracked label on
     a --cz-paper-2 ground — correct for a data table's header row, wrong for a
     criterion that is a sentence. Measured before this block: "Sell directly
     to UAE customers" rendered in caps with 1.75px of tracking and wrapped to
     three lines. */
  color: var(--bz-ink);
  font-size: var(--bz-t-body);
  font-weight: 400;
  letter-spacing: normal;
  line-height: 1.42;
  text-transform: none;
}

.cz-bz--routes .cz-bz__grid .cz-bz__crit-h,
.cz-bz--routes .cz-bz__grid .cz-bz__crit {
  width: var(--bz-key);
  padding-left: 0;
  font-weight: 600;
}

/* THE COLUMN HEAD, AND THE ONLY BEAT `routes` DID NOT HAVE.
   Every other pattern opens on a ground that draws itself — an axis, a spine, a
   stem, a track. This one opened on ten rows fading in under three accent rules
   that were simply already there, so the reader met the data before meeting the
   columns it was in. The 2px rule is now a positioned `::after` rather than a
   border, for one reason: a border cannot be transformed and a bar can, so the
   columns declare themselves left to right and the rows land afterwards.

   IT ALSO STOPS TWO ACCENTS TOUCHING. As a border-bottom the rule ran the whole
   border box, so column one's blue met column two's teal in the gutter at
   1.32:1 — under the 3:1 two adjacent marks need, and the one adjacency the
   header of this file says must never happen. Inset by the gutter it now ends
   where its own text column ends, which is also the correct optical alignment:
   the rule belongs to the words above it, not to the space beside them. */
.cz-bz--routes .cz-bz__grid .cz-bz__route-h {
  position: relative;
  padding-top: 0;
  border-bottom: 0;
  color: var(--bz-hue);
  font-size: var(--bz-t-unit);
  font-weight: 800;
  letter-spacing: .11em;
  line-height: 1.25;
  text-transform: uppercase;
}

.cz-bz--routes .cz-bz__grid .cz-bz__route-h::after {
  position: absolute;
  right: var(--bz-gap);
  bottom: 0;
  left: 0;
  height: 2px;
  background: var(--bz-hue);
  content: "";
  transform-origin: left center;
}

.cz-bz--routes .cz-bz__grid .cz-bz__crit-h {
  border-bottom: 2px solid var(--bz-hair);
}

.cz-bz--routes .cz-bz__grid .cz-bz__cellv {
  display: block;
  color: var(--bz-ink);
  font-size: var(--bz-t-body);
  font-weight: 400;
}

/* THE GRID IS ON THE INNER SPAN AND NOT ON THE CELL. `display: grid` on a `td`
   takes it out of the table formatting context and the column algorithm loses
   it — see the note in cz_biz_routes(). A dialled cell lays the dial and the
   word on one line, with the word never squeezed: the dial is a fixed 20px and
   the text takes the rest. */
.cz-bz--routes .cz-bz__grid .cz-bz__cellin {
  display: block;
}

.cz-bz--routes .cz-bz__grid .cz-bz__cell.has-dial .cz-bz__cellin {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  align-items: start;
  column-gap: 8px;
}

.cz-bz--routes .cz-bz__grid .cz-bz__cell.is-focus .cz-bz__cellv {
  font-weight: 600;
}

/* THE DIAL. Three independent cues, so colour is never the only one:
   fill fraction, hue, and the author's own word beside it (WCAG SC 1.4.1). */
.cz-bz__dial {
  display: block;
  width: 20px;
  height: 20px;
  margin-top: 1px;
  overflow: visible;
}

.cz-bz__dial-seat {
  stroke: var(--bz-hair);
}

.cz-bz__dial--open .cz-bz__dial-seat {
  stroke: var(--bz-rule);
  stroke-dasharray: 2.4 2.6;
}

.cz-bz__dial-arc {
  stroke: var(--bz-hue);
  stroke-dashoffset: 0;
}

.cz-bz__dial-core {
  fill: var(--bz-hue);
}


/* ============================================================
   3. FORK — a flowchart with a decision in it
   ============================================================
   A two-column grid: the spine on the left at a fixed 24px, the text on the
   right. The spine's rules are plain 2px spans that the stylesheet grows, so
   a row's height is decided by its own text and nothing has to be measured in
   advance. Only the NODE is SVG, because only the node has a shape.
   ============================================================ */
.cz-bz--fork .cz-bz__chart {
  display: grid;
  gap: 0;
}

/* TWO COLUMNS, AND EVERY CHILD IS PLACED EXPLICITLY.
   Auto-placement was the bug here and it was invisible until it was looked at:
   an ARM row has two children, not three, so on a `24px 40px 1fr` template the
   elbow took column 1 and the arm's text took the 40px column — sixty-five
   pixels wide, one word per line. Explicit `grid-column` on all three parts
   means a row with a different number of children cannot re-flow the ones that
   are there. */
.cz-bz__stepli {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr);
  align-items: stretch;
  column-gap: var(--bz-gap);
}

.cz-bz__spine {
  display: grid;
  grid-column: 1;
  grid-template-rows: minmax(6px, 1fr) 24px minmax(6px, 1fr);
  justify-items: center;
  width: 24px;
}

.cz-bz__stepbody {
  grid-column: 2;
}

.cz-bz__rule {
  width: 2px;
  min-height: 6px;
  background: var(--bz-rule);
  transform-origin: top center;
}

/* BOTH HALVES OF A ROW'S SPINE GROW FROM THEIR TOP EDGE, so the line travels
   DOWN the chart the way the chart is read. The incoming half used to grow from
   its bottom edge, which is the node sprouting upward into the row above it —
   the opposite of the downward draw cz_biz_fork()'s docblock describes, and
   visible as a stutter at every node. The outgoing half then waits half a step,
   so the line arrives at the node, the node settles, and the line leaves: three
   events in the order a reader follows them, not two at once. */
.cz-bz__rule--in,
.cz-bz__rule--out {
  transform-origin: top center;
}

.cz-bz__rule--void {
  background: none;
}

.cz-bz__node {
  display: block;
  width: 24px;
  height: 24px;
  overflow: visible;
}

.cz-bz__node-seat {
  stroke: var(--bz-rule);
}

.cz-bz__node-mark {
  fill: var(--bz-c1);
}

/* The decision. Gold at ink weight, because this is the one node in the chart
   that is an EMPHASIS rather than a category (R17: gold is emphasis, blue is
   an action a reader takes, and nothing inside a diagram is an action). */
.cz-bz__node--question .cz-bz__node-mark {
  fill: var(--bz-c3);
}

.cz-bz__node--end .cz-bz__node-mark {
  fill: var(--bz-ink);
}

.cz-bz__stepbody {
  display: grid;
  gap: 3px;
  padding: calc(var(--bz-row) * .55) 0 calc(var(--bz-row) * 1.15);
  align-content: start;
}

/* THE ORDINAL MOVED ONTO THE HEADING'S OWN LINE, and it is the cheapest line
   of vertical space in the file. `01` on a line of its own cost one line per
   step — eight of them on /business-setup-consultants-in-dubai/, where the
   chart runs 769px — and it bought nothing, because a number above a heading
   reads as a label for the heading rather than as the heading's own index.
   Beside it, baseline-aligned, it reads as what it is.

   `max-content` for the numeral track and `align-items: baseline` for the first
   row only; the detail below keeps the text column, so the step's own two lines
   stay indented under its words and the hierarchy is carried by position
   instead of by another rule. */
.cz-bz__stepli--step .cz-bz__stepbody {
  grid-template-columns: max-content minmax(0, 1fr);
  align-items: baseline;
  column-gap: 11px;
}

.cz-bz__stepli--step .cz-bz__ord {
  grid-row: 1;
  grid-column: 1;
}

.cz-bz__stepli--step .cz-bz__steph {
  grid-column: 2;
}

.cz-bz__stepli--step .cz-bz__stepd {
  grid-column: 2;
}

/* Quiet, and it stays quiet. The question node, the elbows and the arm labels
   are the gold in this chart and there is only room for one emphasis in it
   (R17); an ordinal is a position, not a point. */
.cz-bz__ord {
  color: var(--bz-quiet);
  font-size: var(--bz-t-unit);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: .1em;
}

.cz-bz__stepli--question .cz-bz__steph {
  color: var(--bz-c3);
  font-size: var(--bz-t-head);
  font-weight: 700;
}

/* The question reads as a question: one hairline above it and one below, the
   full width of the text column. Two rules make a band without becoming a
   fill, which is R17's line on gold and R51's on tints at once. */
.cz-bz__stepli--question .cz-bz__stepbody {
  padding: calc(var(--bz-row) * .9) 0;
  border-top: 1px solid var(--bz-c3);
  border-bottom: 1px solid var(--bz-c3);
  border-top-color: color-mix(in srgb, var(--bz-c3) 48%, transparent);
  border-bottom-color: color-mix(in srgb, var(--bz-c3) 48%, transparent);
}

/* THE ARMS. The elbow stays in the SPINE column, so the line it draws is the
   continuation of the spine and not a second graphic beside it; it is 40px wide
   in a 24px track and overhangs to the right, which costs nothing because it is
   aria-hidden decoration over paper. The arm's text is then indented past the
   arrowhead by a padding rather than by a third grid track — a third track is
   what broke this once (see the note on .cz-bz__stepli). */
.cz-bz__elbow {
  display: block;
  grid-column: 1;
  width: 40px;
  max-width: none;
  height: 40px;
  margin-top: -6px;
  margin-right: -16px;
  overflow: visible;
}

.cz-bz__elbow-path {
  stroke: var(--bz-c3);
  stroke-dashoffset: 0;
}

.cz-bz__elbow-head {
  fill: var(--bz-c3);
}

.cz-bz__stepli--arm .cz-bz__stepbody {
  /* Cleared past where the arrowhead lands, so the turn points AT the text. */
  padding: calc(var(--bz-row) * .45) 0 calc(var(--bz-row) * 1.15) 22px;
}

.cz-bz__stepli--arm .cz-bz__steph {
  color: var(--bz-c3);
  font-size: var(--bz-t-unit);
  font-weight: 700;
  letter-spacing: .075em;
  text-transform: uppercase;
}

.cz-bz__stepli--arm .cz-bz__stepd {
  color: var(--bz-ink);
  font-size: var(--bz-t-body);
}


/* ============================================================
   4. DURATIONS — length IS the duration
   ============================================================
   Stages laid end to end on one scale. --x is where a stage starts, --lo its
   guaranteed floor, --hi the uncertain extension beyond it. The hatch is the
   point of the pattern: a founder asking "how long" is owed the range, not a
   midpoint somebody picked.
   ============================================================ */
/* THE AXIS. A drawn baseline, four hairline ticks and an OPEN head — no
   numbers on any of them. The ticks say "these bars share one scale"; they are
   not a scale a reader is invited to read a value off, because the axis
   maximum is arithmetic nobody checked (R40 — the reasoning is in
   cz_biz_durations(), and the open head is the conventional mark for a scale
   that continues unquantified). */
.cz-bz--durations .cz-bz__axis {
  position: relative;
  display: block;
  height: 12px;
  margin-bottom: 4px;
  /* Room for the head, which sits outside the ruled span. */
  padding-right: 14px;
}

.cz-bz__axissvg {
  display: block;
  width: 100%;
  height: 12px;
}

/* THE ZERO LINE TAKES FULL BLACK; EVERY OTHER RULE STAYS GREY. 23-EXHIBIT §1
   states both halves of that as one rule, and this axis was mid-grey
   (--bz-rule, #8b949d) until 20 September 2026 — so the one mark in `durations`
   that every bar is measured FROM was quieter than the bars themselves, and the
   drawing had no ground. The ticks keep the house gridline grey, which is the
   other half of the same rule and is what stops them competing with the data. */
.cz-bz__axisrule {
  stroke: var(--bz-ink);
  stroke-dashoffset: 0;
}

.cz-bz__tick {
  stroke: var(--bz-grid);
}

.cz-bz__axishead {
  position: absolute;
  right: 0;
  bottom: -2px;
  width: 12px;
  height: 12px;
}

.cz-bz__axishead-mark {
  stroke: var(--bz-rule);
}

.cz-bz--durations .cz-bz__stages {
  display: grid;
  gap: var(--bz-row);
}

.cz-bz__stage {
  display: grid;
  gap: 5px;
  padding-bottom: var(--bz-row);
  border-bottom: 1px solid var(--bz-hair);
}

/* The track every stage's bar is positioned inside. `overflow: hidden` is the
   R5 guarantee: a rounding error at the far end of the scale is clipped here
   and can never reach the page. */
.cz-bz__barwrap {
  position: relative;
  display: block;
  width: 100%;
  height: 12px;
  overflow: hidden;
}

.cz-bz__bar,
.cz-bz__bar-open {
  position: absolute;
  top: 2px;
  height: 8px;
  border-radius: 1px;
  transform-origin: left center;
}

/* The bar's own left offset IS its start on the shared scale, so a reader sees
   elapsed time accumulate down the column. `left` on an absolutely positioned
   child resolves against the wrapper's PADDING box, which is the wrapper's own
   left edge — so the offset is the scale position and nothing else adds to it. */
.cz-bz__bar {
  left: var(--x, 0%);
  width: var(--lo, 0%);
  min-width: 3px;
  background: var(--bz-hue);
  background:
    linear-gradient(
      100deg,
      color-mix(in oklab, var(--bz-hue) 88%, #fff) 0%,
      var(--bz-hue) 62%,
      color-mix(in oklab, var(--bz-hue) 88%, #000) 100%
    );
}

/* THE UNCERTAIN TAIL. Hatched rather than tinted, because a lighter fill reads
   as a smaller quantity and this is not a smaller quantity — it is the same
   quantity, unknown. 45-degree hatching at 5px, which is coarse enough not to
   produce the moiré vibration Tufte files under chartjunk. */
.cz-bz__bar-open {
  left: calc(var(--x, 0%) + var(--lo, 0%));
  width: var(--hi, 0%);
  background:
    repeating-linear-gradient(
      45deg,
      var(--bz-hue) 0,
      var(--bz-hue) 1.6px,
      transparent 1.6px,
      transparent 5px
    );
  box-shadow: inset 0 0 0 1px var(--bz-hair);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--bz-hue) 46%, transparent);
}

/* A stage whose duration could not be read takes the median length and is
   greyed, so it never implies a figure it does not have. */
.cz-bz__stage.is-unmeasured .cz-bz__bar {
  background: repeating-linear-gradient(90deg, var(--bz-hair) 0, var(--bz-hair) 3px, transparent 3px, transparent 6px);
}

/* THE LABEL COLUMN, and it is the same token in four patterns.
   `--bz-key` sizes the criterion column in `routes`, the stage column here, the
   band column in `threshold` and the gate column in `decides`, so all four
   break at the same place and a page carrying several of them reads as one
   grid rather than four.

   The duration sits IN THE NEXT COLUMN rather than flush right, and that is a
   change made after looking: right-aligned on a 759px exhibit it was seven
   hundred pixels from the stage it belonged to, and the duration is the datum a
   reader came for. `buildup` still right-aligns, because a column of money
   aligns on its digits and a column of phrases does not.

   THE NOTE'S OWN MEASURE IS NOW CAPPED. Measured at 1440 on 20 September 2026 it
   ran the exhibit's full width — 674px of 13px type, 81 characters a line, which
   is a note a reader abandons. The cap is --bz-note and the reasoning is there.
   Where the exhibit is wide enough the note moves up beside the duration
   instead; that is THE THREE-PART ROW, below. */
.cz-bz__stagebody {
  display: grid;
  grid-template-columns: var(--bz-key) minmax(0, 1fr);
  align-items: baseline;
  column-gap: var(--bz-gap);
  row-gap: 3px;
}

.cz-bz__stageh {
  grid-column: 1;
}

.cz-bz__dur {
  grid-column: 2;
  justify-self: start;
  color: var(--bz-hue);
  font-size: var(--bz-t-fig);
  font-weight: 700;
  white-space: nowrap;
}

.cz-bz__stagew {
  grid-column: 1 / -1;
}

.cz-bz__stage.is-focus .cz-bz__stageh {
  color: var(--bz-hue);
}


/* ============================================================
   5. THRESHOLD — what changes as a figure crosses a line
   ============================================================
   The ladder is climbed, so the first authored row is at the FOOT and the line
   sits directly above it. The line is the subject of the drawing: it is the one
   mark at full ink weight, it carries the authored figure as real text, and it
   draws last.
   ============================================================ */
.cz-bz--threshold .cz-bz__ladder {
  display: grid;
  gap: 0;
}

.cz-bz__band {
  position: relative;
  display: grid;
  grid-template-columns: 4px minmax(0, 1fr);
  column-gap: var(--bz-gap);
  padding: calc(var(--bz-row) * 1.05) 0;
}

/* THE TINT IS GONE — his screenshot of /difc/, 20 September 2026: *"wth is these
   boxes?"*

   The argument for it was that a band is the INTERVAL, a value the way a bar is a
   length, not a container around a value. Read on the rendered page that argument
   loses: two full-width tinted panels, one blue and one green, stacked with a rule
   between them, read as exactly what R51 forbids — a card. And R51 is his rule,
   not a preference: exhibits carry no card, no border, no shadow, no tint;
   hairlines and marks carry the colour.

   The fill element is kept in the markup and simply draws nothing, because it is
   what the reveal animation scales and removing it from the HTML would mean
   touching every engine that emits a band. The band's own 4px keyline still says
   which side of the threshold it is on, and it still grows out of the line. */
.cz-bz__bandfill {
  display: none;
}

/* THE KEYLINE, AND IT NOW GROWS OUT OF THE THRESHOLD ITSELF. The 4px accent bar
   is the one mark that says which side of the line a band is on, and it used to
   be simply present while everything around it arrived. Given a
   transform-origin at the edge facing the line — bottom for a band above it, top
   for the band below — the two keylines grow away from the line in opposite
   directions, which is the reading of the whole pattern drawn in two gestures.
   The two origins are here, because they are the reading; the transition and the
   pre-state are in the MOTION section with every other one. */
.cz-bz__band::before {
  position: relative;
  z-index: 1;
  grid-column: 1;
  width: 4px;
  height: 100%;
  border-radius: 1px;
  background: var(--bz-hue);
  content: "";
}

.cz-bz__band--under {
  --bz-hue: var(--bz-c2);
}

.cz-bz__band--under::before {
  transform-origin: top center;
}

.cz-bz__band--over {
  --bz-hue: var(--bz-c1);
}

.cz-bz__band--over::before {
  transform-origin: bottom center;
}

/* Same label column as `routes`, `durations` and `decides` — see the note at
   .cz-bz__stagebody. */
/* Same label column and the same row as `durations` — see the note at
   .cz-bz__stagebody, and THE THREE-PART ROW for the wide case. */
.cz-bz__bandbody {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: var(--bz-key) minmax(0, 1fr);
  align-items: baseline;
  column-gap: var(--bz-gap);
  row-gap: 4px;
  padding-right: var(--bz-gap);
}

.cz-bz__bandh {
  grid-column: 1;
}

.cz-bz__bandr {
  grid-column: 2;
  justify-self: start;
  color: var(--bz-hue);
  font-size: var(--bz-t-fig);
  font-weight: 700;
  /* WAS `white-space: nowrap`, WHICH OVERFLOWED EVERY NARROW CONTAINER.
     Measured on /difc/ at a 768px viewport with `overflow-x: clip` lifted: this
     span reached 851px, 83px past the edge. `white-space: normal` was already
     set for it — but only inside `@container bz (min-width: 740px)`, so below
     that width the base rule won and the cell could not wrap at all. The prose
     column at a 768 viewport is about 660px, so the container query never fired
     and the fix never applied where the problem was.
     `nowrap` was protecting a FIGURE from breaking — "AED 5 million", "14 days"
     — and that is the right instinct for a figure and wrong for the clauses
     authors legitimately write here (the same mistaken assumption as B265).
     `text-wrap: balance` keeps a short figure on one line when there is room and
     lets a long one wrap when there is not, which is what was actually wanted. */
  white-space: normal;
  text-wrap: balance;
  overflow-wrap: break-word;
}

.cz-bz__bandw {
  grid-column: 1 / -1;
}

.cz-bz__band.is-focus .cz-bz__bandh {
  color: var(--bz-hue);
}

/* THE LINE. Full ink, full width, with the authored figure sitting on it. */
.cz-bz .cz-bz__line {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px var(--bz-gap);
  margin: 0;
  padding: calc(var(--bz-row) * .8) 0;
}

.cz-bz__linewrap {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: 100%;
  height: 2px;
}

.cz-bz__linesvg {
  display: block;
  width: 100%;
  height: 2px;
}

.cz-bz__linerule {
  stroke: var(--bz-ink);
  stroke-dashoffset: 0;
}

/* The chevron that gives the line a DIRECTION — crossed upward. This is why
   the line is SVG and not a border: the reading is "below this, nothing; above
   it, the obligation", and a border cannot carry that. */
.cz-bz__cross {
  position: absolute;
  top: -7px;
  left: 0;
  width: 14px;
  height: 16px;
}

.cz-bz__cross-mark {
  stroke: var(--bz-ink);
}

.cz-bz__linev {
  /* Cleared past the chevron, so the figure and the mark do not collide. */
  margin-left: 20px;
  color: var(--bz-ink);
  font-size: clamp(17px, 1.7vw, 21px);
  font-weight: 700;
  letter-spacing: -.005em;
  line-height: 1.1;
}

.cz-bz__linek {
  color: var(--bz-quiet);
  font-size: var(--bz-t-unit);
  font-weight: 700;
  letter-spacing: .085em;
  text-transform: uppercase;
}


/* ============================================================
   6. MULTIPLES — identical axes, learn one read all
   ============================================================
   The shared axis is printed ONCE above the grid. Repeating it in every cell is
   what makes a small-multiple set look busy, and the whole point of the form is
   that the axis is learned once.
   ============================================================ */
.cz-bz--multiples .cz-bz__key {
  display: flex;
  flex-wrap: wrap;
  gap: 6px var(--bz-gap);
  margin: 0 0 calc(var(--bz-row) * 1.5);
}

.cz-bz__keyitem {
  display: flex;
  align-items: center;
  gap: 7px;
}

.cz-bz__keyname {
  color: var(--bz-ink);
  font-size: var(--bz-t-unit);
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
}

.cz-bz--multiples .cz-bz__grid-m {
  display: grid;
  /* Two up at 375, three from 621px, four from 1001px — bounded bands below.
     `minmax(0, 1fr)` and not `1fr`: a bare 1fr resolves to min-content on a
     grid item holding a long entity name and blows the track out. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: calc(var(--bz-row) * 1.6) var(--bz-gap);
}

.cz-bz__mult {
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: 8px;
}

.cz-bz__multh {
  font-size: var(--bz-t-note);
  font-weight: 700;
  letter-spacing: .01em;
}

.cz-bz__plot {
  display: flex;
  align-items: stretch;
  /* ONE HEIGHT FOR EVERY CELL. This is the identical axis, and it is the whole
     honesty of the form: the tallest bar in the grid is the largest figure in
     the data, everywhere. */
  height: clamp(64px, 7vw, 92px);
  gap: 4px;
}

/* The spine that makes "identical axes" checkable by eye. Quiet on purpose —
   it is furniture, repeated in every cell, and the one place this file repeats
   furniture at all (see cz_biz_spine()). */
.cz-bz__vaxis {
  flex: 0 0 auto;
  width: 6px;
  height: 100%;
}

.cz-bz__vaxis-line {
  stroke: var(--bz-hair);
  stroke-dashoffset: 0;
}

.cz-bz__vaxis-cap {
  stroke: var(--bz-rule);
}

.cz-bz__col {
  display: flex;
  flex: 1 1 0;
  min-width: 0;
  flex-direction: column;
  justify-content: flex-end;
  gap: 4px;
  height: 100%;
}

.cz-bz__colbar {
  display: block;
  width: 100%;
  /* --h is a percentage of the plot's own height, so every cell shares a scale
     without a single measured pixel. */
  height: var(--h, 0%);
  min-height: 2px;
  border-radius: 1px 1px 0 0;
  background: var(--bz-hue);
  background:
    linear-gradient(
      180deg,
      color-mix(in oklab, var(--bz-hue) 86%, #fff) 0%,
      var(--bz-hue) 74%
    );
  transform-origin: bottom center;
}

.cz-bz__col.is-blank .cz-bz__colbar {
  height: 2px;
  background: var(--bz-hair);
}

.cz-bz__colv {
  color: var(--bz-quiet);
  font-size: var(--bz-t-unit);
  font-weight: 600;
  line-height: 1.2;
  /* A figure under a narrow column has to be allowed to wrap rather than to
     push its cell wider — a grid track that grows on one long number is what
     breaks a small-multiple set's shared scale. */
  overflow-wrap: anywhere;
}

/* The baseline every miniature is seated on, which is what lets the eye read
   across the grid instead of down one cell. */
/* Full black, for the reason .cz-bz__axisrule is: this is the zero line of every
   miniature and the whole claim of a small-multiple set is that they share it
   (23-EXHIBIT §1). The focus cell is still distinguished, by WEIGHT rather than
   by colour — which is the correct channel now that the colour says "zero". */
.cz-bz__base {
  display: block;
  width: 100%;
  height: 1px;
  background: var(--bz-ink);
  transform-origin: left center;
}

.cz-bz__mult.is-focus .cz-bz__multh {
  color: var(--bz-hue);
}

.cz-bz__mult.is-focus .cz-bz__base {
  height: 2px;
  background: var(--bz-ink);
}


/* ============================================================
   7. DECIDES — where the concentration is
   ============================================================
   Gates grouped under the body that owns them, each group hanging off one stem
   whose weight steps up with the number of gates on it. The shape of the
   drawing IS the finding. No count is printed (R40).
   ============================================================ */
.cz-bz--decides .cz-bz__map {
  display: grid;
  gap: calc(var(--bz-row) * 1.9);
}

/* A FLAT MAP CLOSES UP. With five or six bodies, most of them holding one gate,
   1.9 row steps between groups is 1.9 steps between six near-identical blocks —
   the exhibit reads as a list of headings with air between them. The 2px head
   rule is already the separation, so the air comes down to 1.25 and the six
   groups read as one map. Only in the flat case: where four accents still carry
   the categories the groups are genuinely separate objects and keep their
   distance. */
.cz-bz--flat .cz-bz__map {
  gap: calc(var(--bz-row) * 1.25);
}

.cz-bz__group {
  display: grid;
  gap: calc(var(--bz-row) * .8);
}

.cz-bz__who {
  margin: 0;
  padding: 0 0 6px;
  border-bottom: 2px solid var(--bz-hue);
  color: var(--bz-hue);
  font-size: var(--bz-t-unit);
  font-weight: 700;
  letter-spacing: .08em;
  line-height: 1.3;
  text-transform: uppercase;
}

/* THE STEM IS TAKEN OUT OF FLOW, and that is a measured fix rather than tidiness.

   Left in flow it SET the group's height. `<svg height="100">` with
   `height: 100%` resolves the percentage against the grid row, the grid row is
   sized by its tallest item, and with one gate in the group the tallest item
   was the stem falling back to its own 100px attribute — so a one-gate group
   came out 100px tall, its single list row stretched to fill it, and the gate's
   name and its timing ended up forty pixels apart. Measured on the MOHRE group
   before this block.

   Absolutely positioned between `top: 0` and `bottom: 0`, the stem can only
   ever be as tall as the gates beside it, which is what it is for. */
.cz-bz__hang {
  position: relative;
  display: grid;
  grid-template-columns: 8px minmax(0, 1fr);
  column-gap: var(--bz-gap);
}

.cz-bz__stemwrap {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  display: block;
  width: 8px;
}

.cz-bz__stem {
  display: block;
  width: 8px;
  height: 100%;
}

.cz-bz__stem-line {
  stroke: var(--bz-hue);
  stroke-dashoffset: 0;
}

/* Ordinal weights, not proportional: a stroke width is not a quantity anyone
   can measure off a page, so it steps rather than scales. */
.cz-bz__stem--w1 .cz-bz__stem-line { stroke-width: 1.5; }
.cz-bz__stem--w2 .cz-bz__stem-line { stroke-width: 3; }
.cz-bz__stem--w3 .cz-bz__stem-line { stroke-width: 5; }

.cz-bz__gates {
  display: grid;
  grid-column: 2;
  /* `start`, not the default `stretch`: a single-row grid whose container is
     taller than its content spreads that row's own tracks apart. */
  align-content: start;
  gap: var(--bz-row);
}

/* Same label column as `routes`, `durations` and `threshold` — see the note at
   .cz-bz__stagebody. */
.cz-bz__gate {
  display: grid;
  grid-template-columns: var(--bz-key) minmax(0, 1fr);
  align-content: start;
  align-items: baseline;
  column-gap: var(--bz-gap);
  row-gap: 3px;
  padding-bottom: var(--bz-row);
  border-bottom: 1px solid var(--bz-hair);
}

.cz-bz__gateh {
  grid-column: 1;
}

/* `nowrap` came off. A timing phrase is the author's own words and some of them
   are a clause, not a label; held on one line in a track that had already run
   out of room it would have been the one thing in this file capable of pushing
   past the exhibit's right edge. It wraps now, under the same --bz-note cap as
   every other note. */
.cz-bz__gatew {
  grid-column: 2;
  justify-self: start;
}

/* The last gate in a group keeps no hairline: the next group's own 2px head
   rule is already the separation, and two rules a row apart read as clutter. */
.cz-bz__gate:last-child {
  padding-bottom: 0;
  border-bottom: 0;
}

.cz-bz__gate.is-focus .cz-bz__gateh {
  color: var(--bz-hue);
}

/* PAST FOUR BODIES THE ACCENTS STOP BEING AN ENCODING — cz_biz_decides() adds
   `cz-bz--flat` and puts every group on slot 1, and this quiets all of them but
   the body holding the most gates. The reasoning, and the measurement that
   forced it, are in that function.

   Reassigned on --bz-hue rather than by repainting each part, for the reason
   `routes` does the same: custom properties resolve by inheritance, so one
   declaration on the element carrying the slot reaches the head rule, the stem
   and the focus row inside it. Addressed on `.cz-bz__group` alone — the trap in
   the `routes` version of this rule was a descendant selector that also caught
   children with no `.is-lead` of their own and quieted the very group it was
   meant to leave loud. Nothing inside a group carries `.cz-bz__group`. */
.cz-bz--flat .cz-bz__group:not(.is-lead) {
  --bz-hue: var(--bz-quiet);
}


/* ============================================================================
   MOTION

   Every pre-state in this block is qualified by
   `.cz-bz[data-reveal]:not(.visible)`. cz_add_reveal_hooks() puts data-reveal
   on the figure; main.js adds .visible on intersection, or immediately and to
   everything under prefers-reduced-motion or with no IntersectionObserver. So
   the finished exhibit is what renders by default and the animation is the
   exception — never the other way round, which is the failure that once left
   every subheading on the site invisible until an observer fired.

   Only transform, opacity and stroke-dashoffset are touched. No height, no
   width, no margin, no inset: zero layout cost, zero CLS.

   Nothing bounces. --cz-ease-out is cubic-bezier(.16,1,.3,1) and --cz-ease is
   cubic-bezier(.2,.7,.2,1); neither overshoots, and there is no @keyframes in
   this file, so nothing loops and nothing spins.
   ============================================================================ */

/* --- the transitions, on the finished state --- */
.cz-bz__seg,
.cz-bz__bar,
.cz-bz__bar-open,
.cz-bz__colbar,
.cz-bz__bandfill,
.cz-bz__base,
.cz-bz__rule {
  transition: transform var(--bz-in) var(--cz-ease-out, cubic-bezier(.16, 1, .3, 1));
  transition-delay: calc(min(var(--i, 0), 8) * var(--bz-step));
}

.cz-bz__item,
.cz-bz__row,
.cz-bz__stage,
.cz-bz__band,
.cz-bz__mult,
.cz-bz__gate,
.cz-bz__stepbody,
.cz-bz__keyitem {
  transition:
    opacity var(--bz-in) var(--cz-ease, cubic-bezier(.2, .7, .2, 1)),
    transform var(--bz-in) var(--cz-ease-out, cubic-bezier(.16, 1, .3, 1)),
    /* THE HOVER TINT IS DECLARED HERE, WITH THE REVEAL, AND NOT IN THE HOVER
       BLOCK — a bug this file already knew about and then made anyway.

       The note under the small-multiple hover at the foot of the MOTION section
       says it outright: a second `transition` shorthand "would have overwritten
       the reveal's own duration". `.cz-bz--routes .cz-bz__grid tbody tr` scores
       (0,2,1) against this rule's (0,1,0), so its `transition:
       background-color` replaced this whole declaration on every route row.
       Measured on /business-setup-consultants-in-dubai/ at 1600 before this
       change: transition-property `background-color`, transition-delay 0s on
       all seven rows — so on every pointer device at 701px and up the rows had
       NO entrance at all. They held the pre-state and then snapped, with no
       stagger, on the one exhibit that has the most rows to stagger.

       Listed on all eight elements rather than on `.cz-bz__row` alone because a
       transition on a property that never changes never fires, and one list is
       one thing to keep true. */
    background-color .18s var(--cz-ease, cubic-bezier(.2, .7, .2, 1));
  transition-delay: calc(min(var(--i, 0), 8) * var(--bz-step) + var(--j, 0) * 55ms);
}

.cz-bz__node,
.cz-bz__dial,
.cz-bz__swatch,
.cz-bz__elbow-head,
.cz-bz__axishead,
.cz-bz__cross,
.cz-bz__total-v,
.cz-bz__linev,
.cz-bz__linek {
  transition:
    opacity var(--bz-in) var(--cz-ease, cubic-bezier(.2, .7, .2, 1)),
    transform .34s var(--cz-ease-out, cubic-bezier(.16, 1, .3, 1));
  transition-delay: calc(min(var(--i, 0), 8) * var(--bz-step) + 160ms);
}

/* The drawn strokes. Every one of them normalises its own length to 100 with
   `pathLength`, so this rule never has to know a radius, a width or a height —
   the pre-state is simply `--l` and the finished state is 0. */
.cz-bz__dial-arc,
.cz-bz__elbow-path,
.cz-bz__stem-line,
.cz-bz__bracket-path,
.cz-bz__axisrule,
.cz-bz__linerule,
.cz-bz__vaxis-line {
  transition: stroke-dashoffset .7s var(--cz-ease, cubic-bezier(.2, .7, .2, 1));
  transition-delay: calc(min(var(--i, 0), 8) * var(--bz-step) + 120ms);
}

/* The bracket closes the column only once every charge is inside it, so it
   waits for the legend rather than racing it. */
.cz-bz__bracket-path {
  transition-delay: 420ms;
}

/* --- BEAT A: the ground draws --- */
.cz-bz[data-reveal]:not(.visible) .cz-bz__base {
  transform: scaleX(0);
}

.cz-bz[data-reveal]:not(.visible) .cz-bz__rule {
  transform: scaleY(0);
}

/* The half-step that makes the fork's spine travel rather than sprout. The
   incoming rule arrives on the row's own beat, the node settles, the outgoing
   rule leaves half a step later — see the note at .cz-bz__rule--in. */
.cz-bz__rule--out {
  transition-delay: calc(min(var(--i, 0), 8) * var(--bz-step) + 32ms);
}

/* `routes` gets a ground of its own: the accent rule under each column head
   draws left to right, in the order --i puts the columns in, before a single
   row lands. */
.cz-bz__route-h::after {
  transition: transform .42s var(--cz-ease-out, cubic-bezier(.16, 1, .3, 1));
  transition-delay: calc(min(var(--i, 0), 8) * var(--bz-step));
}

.cz-bz[data-reveal]:not(.visible) .cz-bz__route-h::after {
  transform: scaleX(0);
}

/* The axis ticks belong to the axis, so they arrive with the rule that carries
   them. Left alone they were the one thing in `durations` already finished
   before the entrance started. */
.cz-bz__tick {
  transition: opacity var(--bz-in) var(--cz-ease, cubic-bezier(.2, .7, .2, 1));
  transition-delay: 200ms;
}

.cz-bz[data-reveal]:not(.visible) .cz-bz__tick {
  opacity: 0;
}

/* stroke-dashoffset at --l hides the whole stroke; 0 draws it. The arithmetic
   is in cz_biz_dial()'s docblock — pathLength normalises every length to 100,
   so this rule never has to know a radius, a width or a height. */
.cz-bz[data-reveal]:not(.visible) .cz-bz__dial-arc,
.cz-bz[data-reveal]:not(.visible) .cz-bz__elbow-path,
.cz-bz[data-reveal]:not(.visible) .cz-bz__stem-line,
.cz-bz[data-reveal]:not(.visible) .cz-bz__bracket-path,
.cz-bz[data-reveal]:not(.visible) .cz-bz__axisrule,
.cz-bz[data-reveal]:not(.visible) .cz-bz__linerule,
.cz-bz[data-reveal]:not(.visible) .cz-bz__vaxis-line {
  stroke-dashoffset: var(--l, 100);
}

/* --- BEAT B: the data arrives --- */
.cz-bz[data-reveal]:not(.visible) .cz-bz__seg {
  transform: scaleX(0);
}

.cz-bz[data-reveal]:not(.visible) .cz-bz__bar,
.cz-bz[data-reveal]:not(.visible) .cz-bz__bar-open {
  transform: scaleX(0);
}

/* The tail waits for its own floor, so the range reads as an extension of the
   bar rather than as a second bar. */
.cz-bz__bar-open {
  transition-delay: calc(min(var(--i, 0), 8) * var(--bz-step) + 200ms);
}

.cz-bz[data-reveal]:not(.visible) .cz-bz__bandfill {
  transform: scaleY(0);
}

/* The keyline grows away from the threshold, each band in its own direction —
   the two origins are declared with the mark itself, at
   .cz-bz__band--under::before and .cz-bz__band--over::before, because there
   they are the reading rather than the timing. */
.cz-bz__band::before {
  transition: transform var(--bz-in) var(--cz-ease-out, cubic-bezier(.16, 1, .3, 1));
  transition-delay: calc(min(var(--i, 0), 8) * var(--bz-step) + 90ms);
}

.cz-bz[data-reveal]:not(.visible) .cz-bz__band::before {
  transform: scaleY(0);
}

/* ONE BEAT, NOT A STAGGER, inside a small-multiple cell. The moment the
   exhibit is making is a COMPARISON, and animating the columns in sequence
   would invite the reader to read them in sequence. The CELLS stagger; the
   bars inside one cell do not. */
.cz-bz[data-reveal]:not(.visible) .cz-bz__colbar {
  transform: scaleY(0);
}

.cz-bz__colbar {
  transition-delay: calc(min(var(--i, 0), 8) * 60ms + 90ms);
}

.cz-bz[data-reveal]:not(.visible) .cz-bz__item,
.cz-bz[data-reveal]:not(.visible) .cz-bz__row,
.cz-bz[data-reveal]:not(.visible) .cz-bz__stage,
.cz-bz[data-reveal]:not(.visible) .cz-bz__band,
.cz-bz[data-reveal]:not(.visible) .cz-bz__stepbody,
.cz-bz[data-reveal]:not(.visible) .cz-bz__keyitem {
  opacity: 0;
  transform: translate3d(0, 6px, 0);
}

.cz-bz[data-reveal]:not(.visible) .cz-bz__mult {
  opacity: 0;
  transform: translate3d(0, 8px, 0);
}

/* The gates arrive from the LEFT of where they settle, because the direction
   says "these hang off that stem". */
.cz-bz[data-reveal]:not(.visible) .cz-bz__gate {
  opacity: 0;
  transform: translate3d(-8px, 0, 0);
}

/* --- BEAT C: the claim lands --- */
.cz-bz[data-reveal]:not(.visible) .cz-bz__node,
.cz-bz[data-reveal]:not(.visible) .cz-bz__dial,
.cz-bz[data-reveal]:not(.visible) .cz-bz__swatch {
  opacity: 0;
  /* A settle, not a bounce: 1.14 to 1 with an ease-out that does not overshoot
     (R16 — "nothing bounces"). */
  transform: scale(1.14);
}

/* THE DECISION TURNS INTO PLACE. The one node in a fork that is not a step gets
   the one gesture in the chart that is not a settle: a diamond arriving off
   square and squaring up. It reads as the chart stopping to ask something,
   which is what that node is for, and it is still a single ease-out with no
   overshoot — a rotation cannot bounce unless the easing makes it, and neither
   of this file's two easings does. Both neutralising blocks at the foot of the
   file name this selector explicitly rather than relying on a specificity tie. */
.cz-bz[data-reveal]:not(.visible) .cz-bz__node--question {
  opacity: 0;
  transform: scale(1.1) rotate(-32deg);
}

.cz-bz[data-reveal]:not(.visible) .cz-bz__elbow-head,
.cz-bz[data-reveal]:not(.visible) .cz-bz__axishead {
  opacity: 0;
}

/* An arrowhead appears when the rule it terminates has reached it, never
   before — the same beat devices.css established for its own arrowheads. */
.cz-bz__elbow-head,
.cz-bz__axishead {
  transition-delay: calc(min(var(--i, 0), 8) * var(--bz-step) + 520ms);
}

/* The chevron rides in on the line it crosses. */
.cz-bz[data-reveal]:not(.visible) .cz-bz__cross {
  opacity: 0;
  transform: translate3d(0, 4px, 0);
}

.cz-bz__cross {
  transition-delay: 640ms;
}

.cz-bz[data-reveal]:not(.visible) .cz-bz__total-v,
.cz-bz[data-reveal]:not(.visible) .cz-bz__linev,
.cz-bz[data-reveal]:not(.visible) .cz-bz__linek {
  opacity: 0;
  transform: translate3d(0, 5px, 0);
}

.cz-bz__total-v,
.cz-bz__linev,
.cz-bz__linek {
  transition-delay: 460ms;
}

/* A hover that explains something, and nothing that does not. Pointer devices
   only, so a phone tap never leaves a route stuck in a hover state. */
/* BOUNDED AT 701px, not just gated on hover. Below 700px the table restacks
   into one panel per criterion, so a "row" is no longer a row — tinting it
   shades a whole block, which is the opposite of holding the eye on one line.
   And a hover query alone is not enough: a 375px window on a desktop still
   reports `hover: hover`, so the phone layout would take the tint.

   THE TINT IS THE ONLY THING THIS BLOCK DECLARES. Its `transition` moved up to
   the row's own reveal rule, because a shorthand here at (0,2,1) replaced that
   rule at (0,1,0) and took the entrance with it. The reasoning, and the
   measurement, are at .cz-bz__keyitem. */
@media (hover: hover) and (pointer: fine) and (min-width: 701px) {
  /* Reading a wide comparison row is the one genuine comprehension problem in
     this pattern, and a 4% tint is enough to hold the eye on one criterion
     across three columns. It is decoration in the R51 sense only if it carries
     data, and it carries none. */
  .cz-bz--routes .cz-bz__grid tbody tr:hover {
    background-color: color-mix(in oklab, var(--bz-ink) 4%, transparent);
  }
}

/* A LIFT ON HOVER FOR THE SMALL MULTIPLES WAS WRITTEN AND THEN REMOVED, and the
   reason is worth keeping. It explained nothing — R16 allows motion that
   carries meaning, and a cell rising 2px under a cursor carries none — and it
   could not be declared without redeclaring `transition` on .cz-bz__mult,
   which would have overwritten the reveal's own duration and left the
   grid's entrance either instant or lagging behind its stagger delay. One
   hover state in this file, on the one row where reading across three columns
   is a real problem. */


/* ============================================================================
   THE THREE-PART ROW — asked of the EXHIBIT's width, not the window's

   Label, datum, consequence on one line, in the order the sentence is read in.
   It is the right row and it is only the right row when there is room for it:

     at 759px (`step` or wider)  216 + 140 + 380 or more. The consequence sits
                                 beside the figure it belongs to, each row loses
                                 a line, and the five hundred dead pixels to the
                                 right of a 140px figure are gone.
     at 713px (`measure`)        216 + 140 + 283. A 177-character consequence
                                 went from two lines to FOUR in that third
                                 track. Measured on /business-setup-in-dubai/,
                                 and the reason this is a query rather than a
                                 declaration.

   740px is the threshold, which puts `measure` below it and `step` and `bleed`
   above it at every width either of them occurs at. A viewport media query
   cannot make this distinction — two exhibits of different widths sit in the
   same column on the same page — and that is what `container-type` on `.cz-bz`
   is for. Below 620px everything collapses to one column anyway and the query
   cannot match.
   ============================================================================ */
@container bz (min-width: 740px) {
  /* B265 — `max-content` IN THE MIDDLE COLUMN ATE THE THIRD ONE.
     His screenshot of /difc/, 20 September 2026: the threshold exhibit's third
     column had collapsed to roughly one character wide and was setting
     "Qualify / ing / status / is / lost" one word per line, while the middle
     column's sentence ran past the right edge of the figure.
     The middle column was written for a FIGURE — "AED 5 million", "14 days" —
     where `max-content` plus `white-space: nowrap` is exactly right. Authors
     legitimately put a full clause there instead, and `max-content` then claims
     the sentence's entire unwrapped width, leaving `minmax(0, 1fr)` with
     whatever is left, which can be nothing.
     Both columns can now wrap, and the third is guaranteed a readable measure by
     a floor in `ch`, so a long middle can never starve it again.

     24 September 2026 — AND THE CURE OVERFLOWED AT 768px. Measured on /difc/ at
     a 768 viewport with `overflow-x: clip` lifted: `.cz-bz__bandr` reached
     851px, 83px past the edge. Two of the three tracks could refuse to shrink.
     `minmax(18ch, 1.3fr)` is a HARD floor — roughly 144px that no amount of
     pressure removes — and `minmax(0, auto)` resolves `auto` to max-content,
     so a middle column holding a clause rather than a figure claims its whole
     unwrapped width. Add `var(--bz-key)` and the three can exceed the
     container, which is precisely the failure B265 fixed in the other
     direction.
     Proportional tracks solve both at once: every track floors at 0, so the sum
     can never exceed the container, and the fr ratio guarantees the third column
     a share instead of a fixed measure, so it cannot be starved to one character
     either. The third gets the larger share because it carries the consequence
     text while the middle usually carries a figure. */
  .cz-bz__stagebody,
  .cz-bz__bandbody {
    grid-template-columns: var(--bz-key) minmax(0, 1.1fr) minmax(0, 1.4fr);
  }

  .cz-bz__stagew,
  .cz-bz__bandw {
    grid-column: 3;
  }

  /* A figure still refuses to break; a sentence must be allowed to. */
  .cz-bz__bandr,
  .cz-bz__dur {
    white-space: normal;
    text-wrap: pretty;
  }
}


/* ============================================================================
   BREAKPOINTS

   Bounded at both ends wherever a band is not the smallest one.
   reading.css:70 records what an open-ended `max-width: 1400px` did to a 375px
   phone — it matched there too, printed later, and won, leaving the prose
   135px wide. This file does not repeat that.
   ============================================================================ */

/* 1001px and up: the reading grid has a third column, so the step and bleed
   widths have somewhere to grow and a small-multiple set gets four across. */
@media (min-width: 1001px) {
  .cz-bz--multiples .cz-bz__grid-m {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .cz-bz--multiples.cz-bz--series2 .cz-bz__grid-m {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* 1401px AND UP: A THREE-ROUTE COMPARISON TAKES THE MARGIN COLUMN.
   This is the one width decision in the file that is made by the pattern rather
   than by the author, and it is made here rather than in cz_biz_width() so that
   `::width` still has the last word at every other size.

   The measurement it answers, at 1440 on /business-setup-in-uae/, 20 September
   2026: ten criteria across three routes, with cells running to seventy
   characters inside a 162px column — about fifteen characters a line, five lines
   a cell, and 913px of exhibit. At 1500 with the full width the same table is
   721px, its route columns are 285 to 316px, and no cell needs five lines.

   Bounded at 1401px, and that bound is the whole safety of it. --cz-fig-full is
   `calc(100% + margin-col + gap)` only above 1400 — placement.css:492 pins it to
   100% from 1001 to 1400 — so below the bound this rule would make the exhibit
   NARROWER than the step width it already has. R51 allows the move ("wider into
   the margin ... where the data earns it"); a ten-by-three matrix earns it, and
   nothing else in this file asks for it.

   IT READS THE TOKEN RATHER THAN A WIDTH, which is what makes it cooperate with
   the rail form instead of fighting it, and that cooperation is not theoretical.
   `body.cz-railform-on .cz-reading__body` pins --cz-fig-full to 100% at exactly
   this breakpoint, because on those pages R69's form is standing in the margin
   column. Measured twice in one afternoon on 20 September 2026, and the answer
   changed under this rule without the rule changing:

     before the rail form reached these pages, /business-setup-in-uae/ bled to
     1064px at 1440 and 1119px at 1500, and its ten-row table came down from
     913px tall to 672px;
     after it reached them, the same rule resolves to the prose column — 715px at
     1440, 824px at 1600 — and the exhibit does not reach across the form.

   SO ON THE FIVE BUSINESS SETUP PAGES THIS RULE CURRENTLY CHANGES NOTHING, and
   that is the correct outcome rather than a dead rule: `.cz-bz--w-step` was
   already capped at `max-width: var(--cz-fig-full)`, so the width it yields is
   the width they already had. It is kept because it is what a three-route
   comparison should do the moment the margin beside it is free again, and
   because deleting it would mean re-deriving all of the above. One rule, both
   answers, no exception list, nothing to remember.

   Checked for the collision this could have caused: no .cz-marginalia, no rail
   form and no margin figure overlaps either of the two exhibits vertically at
   1500px, because cz_section_is_analytical() already withholds a photograph
   from any section holding one of these. */
@media (min-width: 1401px) {
  .cz-bz--routes.cz-bz--cols3 {
    width: var(--cz-fig-full, 100%);
    max-width: var(--cz-fig-full, 100%);
  }
}

/* 621-1000px: single-column layout, so every exhibit is the column. Three
   miniatures across is the most that keeps a figure legible at this width. */
@media (min-width: 621px) and (max-width: 1000px) {
  .cz-bz--multiples .cz-bz__grid-m {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* Up to 700px: THE COMPARISON TABLE RESTACKS.

   reading.css:460 measured the alternative at 375px — a five-column table
   holding 556px of content in a 343px column, with 213px of it unreachable.
   The brief is explicit that small-screen behaviour is designed and not
   scrolled past, so each criterion becomes its own panel and every cell prints
   its route name from `data-col`. Nothing is hidden, nothing scrolls, and no
   header is lost off the right edge.

   `display: block` on table elements is what does it. The table keeps its
   semantics for assistive technology, which is why the route name is restored
   VISUALLY from a data attribute rather than by duplicating it in the
   markup. */
@media (max-width: 700px) {
  .cz-bz--routes .cz-bz__grid,
  .cz-bz--routes .cz-bz__grid thead,
  .cz-bz--routes .cz-bz__grid tbody,
  .cz-bz--routes .cz-bz__grid tr,
  .cz-bz--routes .cz-bz__grid th,
  .cz-bz--routes .cz-bz__grid td {
    display: block;
    width: auto;
  }

  /* The head row is the column legend and the panels carry their own names, so
     it has nothing left to do. Hidden from sight only: it stays in the
     accessibility tree, where it is still the table's header. */
  .cz-bz--routes .cz-bz__grid thead {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
  }

  .cz-bz--routes .cz-bz__row {
    padding: 0 0 var(--bz-row);
    /* 44px is the R7 touch floor. Nothing here is tappable, but a panel a
       thumb scrolls past still wants the same rhythm. */
    min-height: 44px;
    border-bottom: 1px solid var(--bz-hair);
  }

  .cz-bz--routes .cz-bz__grid .cz-bz__crit {
    width: auto;
    padding: 0 0 6px;
    border-bottom: 0;
    font-size: var(--bz-t-head);
  }

  .cz-bz--routes .cz-bz__grid .cz-bz__cell {
    padding: 6px 0 0;
    border-bottom: 0;
  }

  /* Every cell takes the two-column grid here, dialled or not, so the route
     names and the values line up down the panel whichever way a row went — the
     alignment rule in section 1 applied at phone width. */
  .cz-bz--routes .cz-bz__grid .cz-bz__cell .cz-bz__cellin,
  .cz-bz--routes .cz-bz__grid .cz-bz__cell.has-dial .cz-bz__cellin {
    display: grid;
    grid-template-columns: 20px minmax(0, 1fr);
    align-items: start;
    column-gap: 8px;
  }

  .cz-bz--routes .cz-bz__grid .cz-bz__cell:not(.has-dial) .cz-bz__cellin::before {
    grid-column: 1;
    content: "";
  }

  .cz-bz--routes .cz-bz__grid .cz-bz__cellin::after {
    grid-column: 2;
    order: -1;
    color: var(--bz-hue);
    content: attr(data-col);
    font-size: var(--bz-t-unit);
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
  }

  .cz-bz--routes .cz-bz__grid .cz-bz__cell .cz-bz__dial {
    grid-row: 1 / 3;
  }
}

/* Up to 620px: the narrowest band, and the only one with no lower bound.
   Two miniatures across, the label column released, and every right-aligned
   figure brought back to the left edge — a right-aligned number beside a
   wrapping label is the misalignment the brief is about. */
@media (max-width: 620px) {
  .cz-bz {
    --bz-key: auto;
  }

  .cz-bz--multiples .cz-bz__grid-m {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* EVERY RIGHT-ALIGNED FIGURE COMES BACK TO THE LEFT EDGE. A number set flush
     right beside a label that has started wrapping is the misalignment his
     20 September note is about: the two stop looking like one row. At this
     width each row becomes a single column and the figure sits under its own
     label, on the same left edge as everything else in the exhibit. */
  .cz-bz__stagebody,
  .cz-bz__bandbody,
  .cz-bz__gate {
    grid-template-columns: minmax(0, 1fr);
  }

  .cz-bz__dur,
  .cz-bz__bandr,
  .cz-bz__gatew,
  .cz-bz__stagew,
  .cz-bz__bandw {
    grid-column: 1;
    text-align: left;
    white-space: normal;
  }

  /* buildup keeps its swatch column, so its label, figure and levy stack in
     column 2 and stay aligned with the swatch's right edge. */
  .cz-bz--buildup .cz-bz__item {
    grid-template-columns: 10px minmax(0, 1fr);
  }

  .cz-bz--buildup .cz-bz__figure,
  .cz-bz--buildup .cz-bz__by {
    grid-column: 2;
    text-align: left;
    white-space: normal;
  }

  .cz-bz__stepli {
    grid-template-columns: 20px minmax(0, 1fr);
    column-gap: 10px;
  }

  .cz-bz__spine,
  .cz-bz__node {
    width: 20px;
  }

  .cz-bz__spine {
    grid-template-rows: minmax(5px, 1fr) 20px minmax(5px, 1fr);
  }

  .cz-bz__node {
    height: 20px;
  }

  .cz-bz__elbow {
    width: 30px;
    height: 30px;
    margin-top: -3px;
    margin-right: -10px;
  }

  .cz-bz__stepli--arm .cz-bz__stepbody {
    padding-left: 14px;
  }

  .cz-bz__total {
    justify-content: flex-start;
  }

  .cz-bz__total-k {
    flex: 1 0 100%;
  }
}


/* ============================================================================
   REDUCED MOTION, AND PRINT

   The reduced-motion state is the FINISHED, fully visible exhibit. Every
   pre-state is neutralised, not merely un-transitioned: turning the transition
   off while leaving `opacity: 0` in place is how a reader who asked for no
   motion ends up with a blank rectangle, and it is the one mistake this block
   exists to prevent.

   main.js already adds `.visible` to everything immediately when the reader
   prefers reduced motion, so this is the second of two independent guarantees.
   Print gets the same, because a printed page never gets an observer at all.
   ============================================================================ */
@media (prefers-reduced-motion: reduce) {
  .cz-bz,
  .cz-bz * {
    transition: none;
    animation: none;
  }

  /* `:is()` rather than twenty-three full selectors, so the neutralising list
     can never drift out of step with the pre-state list above it: one place to
     add a mark, and the failure mode of forgetting is a reader who asked for no
     motion getting a blank rectangle. Specificity of `:is()` is its most
     specific argument, and every argument here is one class — so this scores
     (0,3,0) against the pre-states' (0,2,0) plus an attribute, i.e. (0,3,0)
     tied, and wins on source order. */
  .cz-bz[data-reveal]:not(.visible) :is(
    .cz-bz__seg,
    .cz-bz__bar,
    .cz-bz__bar-open,
    .cz-bz__colbar,
    .cz-bz__bandfill,
    .cz-bz__base,
    .cz-bz__rule,
    .cz-bz__tick,
    .cz-bz__item,
    .cz-bz__row,
    .cz-bz__stage,
    .cz-bz__band,
    .cz-bz__mult,
    .cz-bz__gate,
    .cz-bz__stepbody,
    .cz-bz__keyitem,
    .cz-bz__node,
    .cz-bz__dial,
    .cz-bz__swatch,
    .cz-bz__elbow-head,
    .cz-bz__axishead,
    .cz-bz__cross,
    .cz-bz__total-v,
    .cz-bz__linev,
    .cz-bz__linek
  ) {
    opacity: 1;
    transform: none;
  }

  /* THE THREE PRE-STATES `:is()` CANNOT HOLD. A pseudo-element is not a valid
     argument to `:is()`, and `.cz-bz__node--question` scores one class more
     than the `:is()` list it would otherwise sit inside — so all three are
     named in full here rather than left to a specificity tie. Forgetting one
     leaves a reader who asked for no motion looking at a rule of zero width or
     a diamond stuck at thirty-two degrees, which is the exact failure the
     header of this block exists to prevent. */
  .cz-bz[data-reveal]:not(.visible) .cz-bz__route-h::after,
  .cz-bz[data-reveal]:not(.visible) .cz-bz__band::before,
  .cz-bz[data-reveal]:not(.visible) .cz-bz__node--question {
    opacity: 1;
    transform: none;
  }

  .cz-bz[data-reveal]:not(.visible) :is(
    .cz-bz__dial-arc,
    .cz-bz__elbow-path,
    .cz-bz__stem-line,
    .cz-bz__bracket-path,
    .cz-bz__axisrule,
    .cz-bz__linerule,
    .cz-bz__vaxis-line
  ) {
    stroke-dashoffset: 0;
  }
}

@media print {
  .cz-bz[data-reveal]:not(.visible) :is(
    .cz-bz__seg,
    .cz-bz__bar,
    .cz-bz__bar-open,
    .cz-bz__colbar,
    .cz-bz__bandfill,
    .cz-bz__base,
    .cz-bz__rule,
    .cz-bz__tick,
    .cz-bz__item,
    .cz-bz__row,
    .cz-bz__stage,
    .cz-bz__band,
    .cz-bz__mult,
    .cz-bz__gate,
    .cz-bz__stepbody,
    .cz-bz__keyitem,
    .cz-bz__node,
    .cz-bz__dial,
    .cz-bz__swatch,
    .cz-bz__elbow-head,
    .cz-bz__axishead,
    .cz-bz__cross,
    .cz-bz__total-v,
    .cz-bz__linev,
    .cz-bz__linek
  ) {
    opacity: 1;
    transform: none;
  }

  /* The same three `:is()` cannot hold — see the note in the reduced-motion
     block above. */
  .cz-bz[data-reveal]:not(.visible) .cz-bz__route-h::after,
  .cz-bz[data-reveal]:not(.visible) .cz-bz__band::before,
  .cz-bz[data-reveal]:not(.visible) .cz-bz__node--question {
    opacity: 1;
    transform: none;
  }

  .cz-bz[data-reveal]:not(.visible) :is(
    .cz-bz__dial-arc,
    .cz-bz__elbow-path,
    .cz-bz__stem-line,
    .cz-bz__bracket-path,
    .cz-bz__axisrule,
    .cz-bz__linerule,
    .cz-bz__vaxis-line
  ) {
    stroke-dashoffset: 0;
  }

  /* Print never gets the hover tint, and a hatch prints as a hatch. */
  .cz-bz--routes .cz-bz__grid tbody tr:hover {
    background: none;
  }

  /* A figure that breaks across a page loses its own alignment. */
  .cz-bz {
    break-inside: avoid;
  }
}


/* ============================================================================
   DARK GROUNDS

   These exhibits sit on paper on all five Business Setup pages, measured 20
   September 2026 — .cz-prose--article inside .cz-reading__body is #fff. This
   block is here so that a later section on an ink ground does not have to be a
   redesign: the four light accents fail on #050607 (2.64:1 to 4.10:1) and the
   four dark twins clear 8:1, so the switch is one class.

   Deliberately NOT a prefers-color-scheme query. This site has no dark mode;
   the ground is decided by the SECTION, and a media query would repaint an
   exhibit sitting on white.
   ============================================================================ */
.cz-section--ink .cz-bz,
.cz-bz--on-ink {
  --bz-c1: var(--bz-c1-dk);
  --bz-c2: var(--bz-c2-dk);
  --bz-c3: var(--bz-c3-dk);
  --bz-c4: var(--bz-c4-dk);
  --bz-ink: var(--cz-paper, #fff);
  --bz-quiet: var(--cz-lt, rgba(255, 255, 255, .72));
  --bz-paper: var(--cz-ink, #050607);
  --bz-rule: rgba(255, 255, 255, .46);
  --bz-hair: var(--cz-line-dk, rgba(255, 255, 255, .12));
}


/* ============================================================
   NO SCRIPTING — the third guarantee
   ============================================================
   The reveal contract has two guarantees already: the pre-state only exists
   under `[data-reveal]:not(.visible)`, and main.js adds `.visible` to
   everything immediately when the reader prefers reduced motion or the browser
   has no IntersectionObserver. Both of those still need main.js to RUN.

   This is the case neither covers: scripting off, or main.js blocked, or it
   threw before it reached the observer. Without this rule the pre-state would
   be the final state and a bar at scaleX(0) is an invisible exhibit — the
   finished drawing is the default everywhere else in this file and it has to be
   the default here too.

   `scripting: none` is the media feature written for exactly this and it
   cannot false-positive: where it is unsupported the query never matches and
   the other two guarantees carry it, and where it is supported it matches only
   when script genuinely will not run. Cheap insurance against the one failure
   mode that turns an animation into a missing exhibit.
   ============================================================ */

@media (scripting: none) {

  .cz-bz[data-reveal]:not(.visible) * {
    opacity: 1 !important;
    transform: none !important;
  }

  /* Every stroked mark in this file by name. There is no one shared class for
     them — the dial, the elbow, the stem, the bracket, the two axes and the
     threshold line each carry their own — so the list is explicit, and it is
     the same list the pre-state block above uses. */
  .cz-bz[data-reveal]:not(.visible) .cz-bz__dial-arc,
  .cz-bz[data-reveal]:not(.visible) .cz-bz__elbow-path,
  .cz-bz[data-reveal]:not(.visible) .cz-bz__stem-line,
  .cz-bz[data-reveal]:not(.visible) .cz-bz__bracket-path,
  .cz-bz[data-reveal]:not(.visible) .cz-bz__axisrule,
  .cz-bz[data-reveal]:not(.visible) .cz-bz__linerule,
  .cz-bz[data-reveal]:not(.visible) .cz-bz__vaxis-line {
    stroke-dashoffset: 0 !important;
  }
}
