/*
  PROJECT — Oracle / ATG. Optimizing Call Centers.

  Ported from the AxureRP export's projects-oracle.html + files/projects-oracle/
  styles.css. Every coordinate, size, type size, leading and colour below is the
  original's own number, read out of that stylesheet — not estimated from a
  screenshot and not re-derived through transform maths. Where a value departs
  from the source it says so in the same comment, with the reason.

  css/projects-alere.css is the worked example this file follows. Read its
  header first; everything it settled is applied here without re-arguing it:

    * the canvas is `.page` with a stated height and one absolutely-positioned
      `.case` inside it, so every left/top below is the original's own page
      coordinate with no arithmetic in between
    * element order IS paint order — no z-index anywhere, matching the original
    * the icon crowds are <ui-icon> out of the shared kit, never bespoke artwork
    * <b> / <em> mean the same two things they mean on every other page
    * section titles are the cool blue, and the accolade quote marks are the
      Testimonials treatment (both are owner's changes; see below)

  ---------------------------------------------------------------------------
  CANVAS WIDTH — 1444, the source's own

  files/projects-oracle/styles.css sets `body { width: 1444px }` outright, and
  the widest widget on the page (the Results title row, u553) is 1441. So unlike
  Alere — whose 1496 was one over-wide text box hanging off the side — there is
  nothing to reconcile here. --page-width in base.css is already 1444 and is not
  overridden.

  ONE BLOCK IS CLAMPED TO IT, and it is the only width on the page that is not
  the source's: accolade 2. See .accolade-2.

  ---------------------------------------------------------------------------
  THE OWNER'S CHANGES CARRIED OVER FROM ALERE

  1. SECTION TITLES ARE BLUE, NOT GREEN. The source's ._-_title_rows style is
     `rgba(53, 255, 0, 0.7725)` and the Growth Mindset row states #35FF00 at
     full strength; every title row here takes --color-accent-cool instead.
     See .section-title.

  2. THE ACCOLADE QUOTE MARKS are the Testimonials treatment — the same SVG at
     62%, in the cool blue at 0.5 — replacing the source's full-size solid green
     pair. See .accolade blockquote::before.

  3. THE ACCOLADES ARE SET AT THE TESTIMONIALS SIZES and their bands are padding
     around their own content rather than drawn rectangles. See .accolade.

  4. GROWTH MINDSET runs on the site's body leading with the head moved out of
     the heading it collides with. See .growth-head / .growth-text.

  Neither 1 nor 2 is applied any wider than stated. NO TEXT ON THIS PAGE IS
  GREEN ANY MORE — the hero's "High visibility, high priority, high pressure
  project" line was the last of it and went blue in a later pass (see
  .hero-lede .flag), joining the section titles and the accolade credits. The
  green that REMAINS is all ARTWORK and is the source's own: the progress rings,
  the five thumbs, the smiley's mic, the "me" figure in every crowd, and the
  plane's speed trails.

  ---------------------------------------------------------------------------
  ONE WIDGET IS DELIBERATELY NOT PORTED

  u544 — a 1440x126 box at 0,0 filled with a vertical gradient from #41556A
  solid (down to y 70.56) to #41556A at zero alpha (at y 126). It is the FIRST
  widget in the source document, so it paints below everything, and the hero
  photograph (u551, 0,66 1440x337) covers it from y 66 down. The photograph is
  fully opaque — verified by decoding u551.png's alpha channel, min 255 on every
  sampled row — so the only part of u544 that can be seen is 0..66, where it
  paints solid #41556A onto a page whose background is already #41556A.

  It is a no-op. Porting it would add an element that cannot change a pixel.
*/

/* ---------------------------------------------------------------------------
   PAGE SHELL
   --------------------------------------------------------------------------- */

/* .page's only in-flow child is the 66px nav, because .case is absolute. So the
   height is STATED, and this is the one number on the page that is arithmetic
   rather than a source value:

       8444     the last thing on the page — the rendered bottom of
                .growth-text, MEASURED, not the source's drawn box
       + 120    bottom padding, the same figure about-testimonials.css and
                css/projects-alere.css both use

   The source's own page is 8790 (u562 at 8399 + its drawn 391). Two changes
   moved it by 226 net: the Accolades came down to the Testimonials type sizes,
   which took 285 out of that section, and Growth Mindset moved onto the site's
   body leading and the 30px paragraph gap, which GAVE BACK 59 — the source's
   25px leading with a blank line between lessons is tighter than 22.5 plus 30,
   so this is the one place the site's conventions cost height rather than
   saving it.

   .page is border-box (base.css sets it on *), so this height INCLUDES the
   padding rather than adding to it.

   If the copy ever reflows longer, this is the number that has to move. Measure
   it, do not guess it:
       document.querySelector('.growth-text').getBoundingClientRect().bottom */
.page {
  height: 8564px;
}

.case {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
}

/* Everything inside the canvas is placed by the original's own page
   coordinates. Stated once here so no individual rule has to repeat it. */
.case > *,
.cluster > * {
  position: absolute;
}

/* A cluster is a plain positioned box whose children are placed against the
   PAGE, not against the cluster — .cluster itself is a zero-size marker,
   exactly as the source's groups are (every Axure group here is 0,0 0x0). So a
   coordinate inside one is still the source's own page coordinate. */
.cluster {
  left: 0;
  top: 0;
  width: 0;
  height: 0;
}

/* base.css gives every image `max-width: 100%`, and a cluster is deliberately
   ZERO wide — so 100% of it is 0 and any <img> inside one collapses to nothing.
   Measured, not supposed: the two headset bands rendered at offsetWidth 0 with
   their stated 60px and 71px, and nothing on screen said so. The same
   `max-width: none` that components.css puts on .head-frame fixes it, and for
   the same reason. */
.cluster img { max-width: none; }

/* The page's own paint server. The kit injects #kit-sheen and #kit-slate for
   every page; this ramp is Oracle's alone — the source fills three heads and
   the aeroplane with #57697c -> #a5b6cb, which is neither of the kit's two.

   It is declared in the HTML as a real <defs>, not here, because an SVG fill
   cannot take a CSS gradient. The two orientations the source uses:

       #oracle-dome    vertical, dark at the bottom   (the three large heads)
       the aeroplane   horizontal                     (baked into plane.svg) */

/* ---------------------------------------------------------------------------
   IN-SENTENCE EMPHASIS
   ---------------------------------------------------------------------------
   The same two forms as every other page in this rebuild:

       <b>       strong — a weight change AND the warm yellow
       <em>      colour only, at body weight, no italic

   plus ONE more that this page needs and Alere did not:

       <strong>  a weight change with NO colour change

   The source uses it four times — "We learned that", "million", "36 furious
   clients", "200,000+ users" — all Kumbh Bold in plain white. Writing those as
   <b> would have coloured them yellow; writing them as <em> would have dropped
   the weight. They are a third thing and they are marked as one.

   700, not Alere's 900: this page's bold runs are Kumbh Bold throughout. The
   two blocks whose source weight differs override it beside their own copy —
   .analysis-text (Regular 400), .growth-text (Medium 500) and .accolade
   (ExtraBold 900).

   DECLARED HERE, AT THE TOP, and not beside the copy it applies to. `.case b`
   and `.growth-text b` are the same specificity (0,1,1), so whichever comes
   LAST in the file wins; generic before specific lets the overrides win without
   either rule having to inflate its selector. */
.case em {
  font-style: normal;
  font-weight: var(--font-weight-body);
  color: var(--color-emphasis);
}

.case b {
  font-weight: 700;
  color: var(--color-emphasis);
}

.case strong {
  font-weight: 700;
  color: inherit;
}

/* ---------------------------------------------------------------------------
   LETTER-SPACING
   ---------------------------------------------------------------------------
   Nearly every text widget on this page carries Axure's `_-_h3` style, whose
   global definition (data/styles.css) sets `letter-spacing: 0.5px`. That is
   different from Alere, where only two blocks had it and each stated its own —
   here it is the rule rather than the exception, so it is stated ONCE for the
   blocks that carry it.

   The four `paragraph`-class blocks (u646, u751, u776, u874) state the same
   0.5px inline, so they belong in the same list.

   NOT in it, because the source gives them none: the title rows
   (`_-_title_rows`), the hero title (`shape`), the accolade quotes
   (`_-_box_-_no_bg_-_white_txt`), the orange plate (`box_3`) and the UI
   fragments drawn on the two screenshots. */
.hero-lede,
.brief-list,
.action-text,
.action-label,
.callout,
.journey-text,
.stage-label,
.stage-text,
.results-list,
.results-note,
.ring-value,
.growth-text,
.section-title .aside {
  letter-spacing: 0.5px;
}

/* ---------------------------------------------------------------------------
   HERO — the photograph, the client badge, the title and the lede
   --------------------------------------------------------------------------- */

/* u551, 0,66 1440x337. The canvas is 1444 wide, so the source leaves a 4px
   sliver of page colour down the right-hand side of the photograph — the same
   edge Alere has, and it is kept. */
.hero-photo {
  left: 0;
  top: 66px;
  width: 1440px;
  height: 337px;
  object-fit: cover;
}

/* u552 — the vignette that darkens the left-hand side of the photograph enough
   to carry white type.

   The source is an SVG radial gradient in userSpaceOnUse coordinates with a
   gradientTransform, so it has to be resolved rather than copied:

       centre  1092.857, 161.342   r 500.206
       matrix  (1 0 0 0.5498265850933852 0 72.63191026066528)

   Applying the matrix to the centre gives (1092.857, 161.342) back — it lands
   on itself exactly, because 0.54983 x 161.342 + 72.632 = 161.342 — so the
   transform's only real effect is the 0.54983 on the y axis, which turns the
   circle into an ellipse:

       rx  500.206 x 1        =  500.2
       ry  500.206 x 0.54983  =  275.0

   Three stops, all the source's: page colour at zero alpha in the middle, page
   colour at 28.2% at 37%, and #202F41 at 83.1% at the rim. The inner stop is
   written as page-colour-at-zero-alpha rather than `transparent`, because
   `transparent` is black-at-zero in some engines and would grey the ramp. */
.hero-scrim {
  left: 0;
  top: 66px;
  width: 1440px;
  height: 337px;
  background: radial-gradient(
    500.2px 275px at 1092.9px 161.3px,
    rgba(65, 85, 106, 0) 0%,
    rgba(65, 85, 106, 0.282) 37%,
    rgba(32, 47, 65, 0.831) 100%
  );
}

/* The client badge. Appearance comes from components.css (.logo, .logo-mark,
   .logo-shadow); this supplies position and the one size that differs.

   The shared component is authored at the case-study CARD's 64px circle. Here
   the circle is the source's 102px (u706) and the two contact ellipses are
   160x22 and 94x15 (u704, u705) — the same three numbers Alere's hero uses, so
   this composition is one Axure master reused across the project pages.

   Blue, not the cards' grey: u706 fills the circle rgba(63, 100, 206), which is
   --color-case-study-blue exactly, so .logo-blue applies unchanged. */
.hero-logo {
  left: 48px;
  top: 121px;
  width: 102px;
  height: 102px;
}

/* The mark lives INSIDE the circle, so its offsets are circle-relative rather
   than page coordinates. Subtracting the circle's own origin:

       u707  51,166 98x13   minus   u706  48,121   ->   3,45

   The file is images/logos/oracle.png, which v2 already carries for the
   projects-start card. It is byte-for-byte the asset the source references here
   as images/projects-start/u77.png — same 1926x243 original — so nothing new
   was copied in for it. */
.hero-logo-mark {
  left: 3px;
  top: 45px;
  width: 98px;
  height: 13px;
}

/* .logo-shadow states its own left/width/height for the 64px circle, so all
   four have to be overridden here, not just the ones that differ.

   THE SELECTOR NEEDS BOTH CLASSES. components.css writes `.logo-shadow.wide`,
   which is two classes; a single-class rule here loses the cascade to it and
   the shadow silently keeps the 101x14 card size. */
.logo-shadow.hero-shadow-wide {
  left: 19px;
  top: 205px;
  width: 160px;
  height: 22px;
}

.logo-shadow.hero-shadow-tight {
  left: 52px;
  top: 212px;
  width: 94px;
  height: 15px;
}

/* u708. Josefin Light 46 — the same face and weight the case-study cards use
   for their titles. The source centres the text in a 56px box; `display: flex`
   + `align-items: center` reproduces that rather than guessing a top. */
.hero-title {
  left: 179px;
  top: 149px;
  width: 690px;
  height: 56px;
  margin: 0;
  display: flex;
  align-items: center;
  font-family: var(--font-heading-light);
  font-weight: 200;
  font-size: 46px;
  line-height: 1;
  color: var(--color-white);
}

/* u709 — the same sentence the projects-start card carries. 19/26 at 0.71
   opacity, all three the source's.

   THE DROP SHADOW IS THE SOURCE'S TOO (`#u709_div`), and it is kept because
   this lede sits over the lit part of the photograph where the vignette has
   almost no strength left; the title above it is 46px and does not need the
   help, which is why the source only puts it here. */
.hero-lede {
  left: 179px;
  top: 205px;
  width: 553px;
  margin: 0;
  font-family: var(--font-body-light);
  font-weight: 200;
  font-size: 19px;
  line-height: 26px;
  opacity: 0.71;
  filter: drop-shadow(1px 0 2.5px rgba(0, 0, 0, 0.675));
}

.hero-lede p {
  margin: 0;
}

/* The second line. The source paints it #35FF00; it is the cool blue now —
   owner's call, and it brings the last of this page's green TEXT into the blue
   change that the section titles and accolade credits already took. The green
   that remains on the page is all artwork: the rings, the thumbs, the smiley's
   mic, the plane's speed trails and the "me" figure in the five crowds. */
.hero-lede .flag {
  color: var(--color-accent-cool);
}

/* ---------------------------------------------------------------------------
   SECTION TITLE ROWS
   ---------------------------------------------------------------------------
   Eight of these: Services, Software, Time / Team, My Tasks, My Actions,
   Results, Accolades, Growth Mindset. In the source each is a text widget with
   a background SVG behind it; both halves are reproduced here in one element.

   THE BAND IS NOW FIGMA'S (owner, 2026-10-12): background reads
   --section-break-fade from base.css. What follows records the EXPORT'S band.
   THE BAND (export). A horizontal gradient, white 4.3% -> 1.2%. The source draws it per
   title at that title's own width, and every one of them uses the same two
   proportions — the fade starts at 56.9% of the width and finishes at 99.8%:

       u555 (1440 wide)   x1 819.14 -> 56.885%    x2 1437.63 -> 99.836%
       u553 (1441)        x1 819.71 -> 56.885%    x2 1438.63 -> 99.835%
       u644  (570)        x1 324.24 -> 56.885%    x2  569.06 -> 99.836%
       u560  (417)        x1 237.21 -> 56.884%    x2  416.31 -> 99.836%

   So the stops are percentages, not the pixel figures, and one rule covers all
   eight at whatever width each is given. They are the same two proportions
   Alere's title rows use, which is what proves this is one Axure style rather
   than eight hand-drawn gradients.

   THE TEXT sits on the BOTTOM of the 65px band, indented 66px — the source's
   `align-self: flex-end; padding: 2px 2px 0px 66px`.

   THE COLOUR IS THE OWNER'S CHANGE, carried over from Alere unchanged: the
   source is `rgba(53, 255, 0, 0.7725)` (and #35FF00 at full strength on the
   Growth Mindset row); it is --color-accent-cool here, at full strength. The
   type size, weight, face and indent are all untouched. */
.section-title {
  height: 65px;
  margin: 0;
  display: flex;
  align-items: flex-end;
  padding: 0 2px 0 66px;
  font-family: var(--font-body-light);
  font-weight: 200;
  font-size: 30px;
  line-height: 1.2;
  color: var(--color-accent-cool);
  background: var(--section-break-fade);   /* Figma's; see base.css */
}

/* "Growth Mindset" is followed on the same line by "What I learned:" in white
   at 49.8%. In the source that gap is a run of non-breaking spaces — authoring,
   not typography — so it is a real margin here instead.

   152 IS THE FIGURE ALERE ARRIVED AT, and it is right for the same reason and
   by the same arithmetic, because the two pages set the same string at the same
   size from the same x:

       "Growth Mindset" ink   224.0 at 30px Kumbh Light, from x 66  -> ends 290
       head width             104
       gap either side        24     (the one chosen number)
       head left              290 + 24         =  314
       aside starts           314 + 104 + 24   =  442
       margin-left            442 - 290        =  152

   See .growth-head for why the head moves into that gap at all. */
.section-title .aside {
  margin-left: 152px;
  color: rgba(255, 255, 255, 0.498);
}

.title-services  { left: 0;    top: 405px;  width: 570px; }
.title-software  { left: 570px; top: 405px; width: 417px; }
.title-team      { left: 1023px; top: 405px; width: 417px; }
.title-tasks     { left: 0;    top: 761px;  width: 1440px; }
.title-actions   { left: 0;    top: 1155px; width: 1440px; }
.title-results   { left: 0;    top: 5994px; width: 1441px; }
.title-accolades { left: 0;    top: 7012px; width: 1440px; }
.title-growth    { left: 0;    top: 8030px; width: 1440px; }

/* ---------------------------------------------------------------------------
   THE BRIEF — Services / Software / Time / Team, then My Tasks
   --------------------------------------------------------------------------- */

/* Shared shape for the four lists under the first two bands. They are <ul>s
   here rather than the source's run of <p>s, because they ARE lists — but they
   are NOT marked: the original shows no bullets and neither does this. */
.brief-list {
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 19px;
  color: var(--color-white);
}

/* u643, u891, u558. All three 19/35, and each starts at its own band's 66px
   indent plus a pixel or two of the source's own hand slop (67 against 66,
   638 against 636, 1091 against 1089). Those are the source's numbers and they
   are kept: the three columns agreeing with each other is what matters, and
   they do — the gaps between them are 571 and 453, which is the bands' own
   570/453 to within a pixel.

   THE SITE'S -25% LEADING RULE DOES NOT APPLY HERE, and that is a decision, not
   an oversight. base.css sets --line-height-body to 22.5px as a site-wide
   reduction of Axure's 30px body leading. This page's lists are not authored at
   30: they run 19/35 and 19/25. Pushing a 19px face onto 14.25px would put the
   lines through each other. Where the source's own leading is used it is stated
   per block. */
.services-list { left: 67px;   top: 481px; width: 481px; line-height: 35px; }
.software-list { left: 638px;  top: 481px; width: 289px; line-height: 35px; }
.team-list     { left: 1091px; top: 481px; width: 289px; line-height: 35px; }

/* The count and the role are two different faces in the source — Kumbh Light
   for the figure, Kumbh Thin for the words. Both resolve to weight 200, so the
   distinction survives only as a face change, which is why .count exists rather
   than a weight. Same construction as Alere's Time / Team list. */
.team-list .count { font-family: var(--font-body-light); }

/* u554. 19/25 with a blank line between items, so the pitch is 50 and the gap
   is one full blank line. The source writes those blanks as empty <p>s; here
   they are the margin between list items, which is the same 25px and cannot
   drift out of step with the leading. */
.task-list {
  left: 64px;
  top: 838px;
  width: 1319px;
  line-height: 25px;
}

.task-list li + li { margin-top: 25px; }

/* ---------------------------------------------------------------------------
   MY ACTIONS — one crowd, its paragraph and its label
   ---------------------------------------------------------------------------
   The crowd looks like bespoke artwork and is not. Every figure in it — and in
   the four other crowds further down the page — is <ui-icon> out of the shared
   kit (js/icons.js):

       torso + head    a person. Placed as TWO icons, never one composed
                       "person" shape, because this page uses seven different
                       head-to-torso offsets (45/28, 39/24, 35/22, 33/21, 30/19,
                       29/18, 89/55) and a welded pair would be wrong for six of
                       them. That is the same reason the kit dropped its
                       composed person.
       speech          the bubble, flipped on x where it points the other way
       rect            every screen outline, base bar, bubble and earcup

   Colour carries the meaning, and it is the source's:

       green #35FF00       the one figure that is Jesse, in every crowd
       white at 49.8%      the stakeholder being worked WITH
       #a0aab4 grey        the wider group being worked FOR
       url(#kit-slate)     every torso, without exception — the source fills all
                           twenty-eight with the same #56687a -> #798796 ramp,
                           which is --kit-slate in base.css
       url(#oracle-dome)   the three LARGE heads (46px and 55px), which the
                           source lights from above with #57697c -> #a5b6cb
                           instead. The small heads are flat; only these three
                           are modelled. */

/* .fig-torso / .fig-me / .fig-with / .fig-for / .fig-say NOW LIVE IN
   components.css. They moved the day About > Process reused this crowd for its
   Stakeholder Discovery step — a second consumer is exactly the condition
   CLAUDE.md sets for hoisting a page-local class, and the alternative was the
   same five names declared identically in two page stylesheets, where changing
   one and forgetting the other is silent.

   The values did not change, only the file. .fig-dome stays here: its paint
   server is #oracle-dome, which is this page's own <defs> and exists nowhere
   else. */
.fig-dome  { --icon-fill: url(#oracle-dome); }

/* u645 and u630. The one action on this page: a paragraph on the left, the
   crowd in the middle, the label on the right.

   The label is 30px in the source's pale yellow #FFECA9, which is NOT
   --color-emphasis (#FFE073): the two are different colours in the original and
   the paler one is used only for these labels, so it is written literally
   rather than borrowed from a token that means "in-sentence emphasis". */
.action-label {
  margin: 0;
  font-family: var(--font-body-light);
  font-weight: 200;
  font-size: 30px;
  line-height: 1.2;
  color: #ffeca9;
  white-space: nowrap;
}

.label-relationships { left: 919px; top: 1262px; width: 186px; }

.action-text {
  margin: 0;
  font-size: 19px;
  /* 25, not the source's 34. u645 is the only paragraph on the page set on 34
     and at 19px it reads as a gap rather than as leading; 25 is what every
     other block here uses. */
  line-height: 25px;
  color: var(--color-white);
}

.text-research { left: 64px; top: 1240px; width: 611px; }

/* ---------------------------------------------------------------------------
   THE ORIGINAL PLATFORM — the annotated screenshot
   --------------------------------------------------------------------------- */

/* u634. Orange plate, white type. #FF9100 is the source's and it is used twice
   on this page — here and on the curved arrow that hooks out of it — so the two
   are tied together by the same literal rather than by a token. It is
   deliberately NOT --color-emphasis: this is a label, not emphasis inside a
   sentence, and the two are visibly different oranges in the original.

   CENTRED IN THE PLATE, following Alere. The source pads the text 2px on every
   side and centres it only VERTICALLY, so the type sits hard against the left
   edge with empty orange trailing it. Centring on both axes is what gives the
   three gripes below something to line up on. */
.platform-label {
  left: 111px;
  top: 1415px;
  /* 320.6, solved rather than chosen. The label is centred, its ink measures
     252.6 at 26px Kumbh Regular (Range over the rendered element), and the
     gripes' text now inks at 145:
         111 + (W - 252.6) / 2 = 145   ->   W = 320.6
     so the "T" sits on the "L" below it. Re-measure the ink if the copy or the
     face ever changes; the width is downstream of it. */
  width: 320.6px;
  height: 64px;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2px;
  background: #ff9100;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 26px;
  line-height: 1.2;
  color: var(--color-white);
}

/* The three complaints under the plate, each carrying a short orange dash —
   Alere's treatment, and it does the same two jobs here: it ties them back to
   the plate by colour, and it indents the text onto the plate's own centred
   type.

   THE 34px INDENT closes the gap between the dash and its text to 10px — the
   dash runs 111..135 and the text ink now starts at 145. It was 21px, which read
   as two separate things rather than one bullet.

   THE PLATE FOLLOWS THE TEXT, not the other way round: its label is centred, so
   its width is solved to put the "T" of "The original platform" on the "L" of
   "Looks circa 1985". See .platform-label.

   The bullet is ONE SOLID DASH, 5px thick, in the plate's own #FF9100 — it was
   the leader lines' 4-on-4-off pattern, and now that dashes mean "the story
   moves on" everywhere else on this page, a dotted bullet was saying something
   it did not mean. */
.platform-gripes {
  left: 111px;
  top: 1493px;
  width: 261px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 19px;
  line-height: 29px;
  color: var(--color-white);
  letter-spacing: 0.5px;
}

.platform-gripes li {
  position: relative;
  padding-left: 34px;
}

.platform-gripes li::before {
  content: "";
  position: absolute;
  /* 3, not 0: a 7px gap between dash and text, the same as Alere and Manual
     Quoting (owner, 2026-10-12). The dash moves, not the text, because the
     text's 34px indent is what puts "Looks" under the plate's "T". */
  left: 3px;
  top: 50%;
  width: 24px;
  height: 5px;
  transform: translateY(-50%);
  background: #ff9100;
}

/* u635 — the orange arrow hooking off the plate down onto the screenshot.

   The source rotates a 148x36 element about ITS OWN centre, but the artwork
   file is 165x53 sitting at -3,-3 inside that element (the stroke's half-width
   plus the arrowhead's overhang). Place the file at its own page position and
   the two centres no longer agree, so the rotation origin is stated in the
   file's coordinates rather than left at 50% 50%:

       element   323,1536  148x36  ->  centre 397, 1554
       file      320,1533  165x53  ->  origin 397-320, 1554-1533  =  77, 21

   Leaving it at 50% 50% would swing the arrowhead several px off the screen it
   points at. The same correction is applied to the swoosh below; it states its
   own arithmetic. */
.arrow-curved {
  left: 320px;
  top: 1533px;
  width: 165px;
  height: 53px;
  transform: rotate(67.89741174662048deg);
  transform-origin: 77px 21px;
}

.platform-shot {
  left: 329px;
  top: 1632px;
  width: 852px;
  height: 522px;
}

/* ---- callouts ------------------------------------------------------------- */

/* The annotations around both screenshots. 13px on 17, not the source's 19 on
   51-or-25 — both owner's calls, and together they rebuilt every `top` on this
   page, so read this before touching one.

   THE SOURCE'S CONSTRUCTION, which these rules no longer use: 19px type in a box
   whose stated top is the widget's page coordinate, on a leading that is 51 for
   nine of the labels and 25 for the other nine. A 51px line box around 19px type
   puts the ink 16px below the box top; the arrows were aimed at where that lands,
   so the two leadings are load-bearing and could not simply be normalised.

   WHAT THEY USE NOW: one leading, 17px, for every label. The type came down to
   13px in two steps (19 -> 15 -> 13) and the 25/51 leadings then read as very
   loose. 17 is the source's own 25/19 ratio carried over — 13 x 1.31.

   HOW THE TOPS WERE DERIVED. `top` states a box, but what has to land in the
   right place is the INK, so every one of them is now written as

       top = (the arrow's own centre y) - lines x 8.5

   i.e. the label's text block is centred on its arrow. That is the rule for all
   but four: .callout-orange and .callout-copy sit above a downward arrow, and
   .callout-phantom / -blue / -green below an upward one, so those four keep a
   stated offset instead. Converting the old boxes is `top += 17` for a
   single-line 51 and `top += 4` for a single-line 25; multi-line labels were
   recomputed from the formula.

   THREE LABELS ARE NOT 13px. .callout-search / -context / -options stay at the
   source's 19 on 25 — owner's call, they are the yellow labels under the search
   bar and they read as a caption rather than as a pointer label. */
.callout {
  margin: 0;
  font-size: 13px;
  line-height: 17px;
  color: var(--color-white);
}

/* --- around the original platform (u710) --- */
/* Centred over their own pointers rather than left-aligned, because each one
   names a specific control in the screenshot below it. The x is the control's
   own — the orange X beside the ORDER save icon at 597, the (i) beside
   "Copy Order" at 888.5, both read off the rendered screenshot — but the arrows
   stop at the screenshot's top edge rather than running down to the control.
   Owner's rule: a pointer barely touches the perimeter of the thing it is about
   and points AT it; it does not land on it. See .leader-orange / .leader-copy. */
.callout-orange      { left: 497px;  top: 1546px; width: 200px; text-align: center; }
.callout-copy        { left: 738.5px; top: 1546px; width: 300px; text-align: center; }

/* THE TIGHTEST PACKING ON THE PAGE, and the one place where the "centre the
   label on its arrow" rule is broken on purpose. Two arrows 22.5px apart — the
   tab strip at 1708.5 and the sub-nav row under it at 1731 — carrying a one-line
   and a two-line label, 49px of ink between them. Centring both overlaps them by
   2px. So .callout-tabs sits 4px high of its arrow, and .callout-orders aligns
   its FIRST LINE to its arrow and hangs the rest below (which is what the source
   itself does for a tall label). That leaves a 10.5px gap. Do not add a third
   pointer here, and do not "fix" either offset without re-measuring the pair. */
.callout-tabs        { left: 10px;   top: 1696px; width: 246px; text-align: right; }
.callout-orders      { left: 0;      top: 1722.5px; width: 256px; text-align: right; }

/* The source hangs this from a stated top because at 19px it is a four-line
   block and its arrow points at the first line. At 13px it is two lines, so it
   is centred on the arrow instead — which is what the rest of this column does. */
.callout-jumbled     { left: 1248px; top: 1659.5px; width: 181px; }
.callout-utilities   { left: 1246px; top: 1718.5px; width: 183px; }
.callout-crucial     { left: 1246px; top: 1806px; width: 183px; }
.callout-duplicate   { left: 1246px; top: 1877px; width: 183px; }
.callout-nested      { left: 0;      top: 1898px; width: 256px; text-align: right; }
.callout-bold        { left: 0;      top: 2017px; width: 256px; text-align: right; }

/* The three under the screenshot point UP, so their labels sit below the arrow
   rather than beside it — and they are the only three whose ink was not centred
   on the arrow's x. The source left-aligns them in a box wider than the text,
   which held at 19px by luck; at 13px the ink lost ~30px of width and drifted
   left of the arrow. Centred in a box whose own centre IS the arrow's x. */
.callout-phantom     { left: 352px;   top: 2231px; width: 207px; text-align: center; }
.callout-blue        { left: 674px;   top: 2231px; width: 205px; text-align: center; }
.callout-green       { left: 842.5px; top: 2231px; width: 374px; text-align: center; }

/* The source sets this one to 18 rather than 19, to keep "Unnecessary feature"
   on one line in a 189px box. At 13px it fits with 55px to spare, so the
   exception is gone and the whole column is one size. */
.callout-unnecessary { left: 1246px; top: 1988px; width: 189px; }

/* u717 carries `opacity: 0.1` in the source — a joke about the feature it names.
   Owner's call to drop it: at 10% it read as a rendering fault rather than as a
   gag, so this callout and its leader are now the same weight as the others. */
.callout-useless     { left: 1246px; top: 2109px; width: 183px; }

/* --- around the redesign (u782) --- */
/* Six of these are the source's. Five more are the owner's additions, and the
   rule for placing every one of them is the same: the label's TEXT BLOCK is
   centred on its own arrow, and the arrow is aimed at a row of the screenshot
   read off the render (crop offsets are page y, the screenshot spans 4182..4785):
       call/tool icon row      4218      unified search + call controls
       primary tool cluster    4250      Jennifer Williamson / Order / Products
       item table              4358      "All clutter = gone"
       a flat table row        4470      "All nesting -> Removed"
       Order Discount: $10     4505      "Consistent text link colors"
       shipping address block  4662      "Adaptive context..."
   .callout-switchers was the one label whose text sat 8.5px BELOW its arrow
   rather than centred on it; it is now centred like the rest. */
.callout-switchers   { left: 1259px; top: 4197.5px; width: 176px; }
.callout-icons       { left: 1259px; top: 4241.5px; width: 176px; }
.callout-callmech    { left: 12px;   top: 4211px; width: 182px; text-align: right; }
.callout-primary     { left: 12px;   top: 4239px; width: 182px; text-align: right; }
.callout-contrast    { left: 26px;   top: 4356.5px; width: 168px; text-align: right; }
.callout-clutter     { left: 1259px; top: 4351px; width: 176px; }
.callout-nesting     { left: 1259px; top: 4461.5px; width: 176px; }
.callout-links       { left: 26px;   top: 4496.5px; width: 168px; text-align: right; }
/* At 19px this needed its own size and a wider box to stay on one line; at 13px
   it fits the column's own 168 and is back on the shared left edge. */
.callout-clear       { left: 26px;   top: 4544px; width: 168px; text-align: right; }
/* Two lines, and its two arrows are aimed at those two lines rather than at the
   buttons — see .leader-buttons-a / -b, which records what that cost. */
.callout-buttons     { left: 1259px; top: 4642.5px; width: 176px; }
.callout-adaptive    { left: 26px;   top: 4637px; width: 168px; text-align: right; }

/* --- under the search bar --- */
/* u641 / u777 / u779. The three that KEEP the source's 19px on 25 — owner's
   call; they caption the search-bar illustration rather than annotate a
   screenshot, and the illustration is drawn at four times life size.
   Their `left` is the source's + 4.5: all three boxes are stated 4.5px left of
   their own arrow, which centring the text inside them inherits. */
.callout-search  { left: 257.5px;  top: 3957px; width: 154px; font-size: 19px; line-height: 25px; text-align: center; color: var(--color-emphasis); }
.callout-context { left: 622.5px;  top: 3957px; width: 154px; font-size: 19px; line-height: 25px; text-align: center; color: var(--color-emphasis); }
.callout-options { left: 1016.5px; top: 3957px; width: 154px; font-size: 19px; line-height: 25px; text-align: center; color: var(--color-emphasis); }

/* ---- leader lines --------------------------------------------------------- */

/* A dashed line with a solid arrowhead on its far end. Twenty-three of them,
   and the only thing that varies is length and rotation, so they are CSS rather
   than twenty-three SVG files — unlike the curved arrow and the swoosh, which
   bend.

   Read straight off the source's own geometry (u638 is the worked example; the
   others are identical bar their length):

       element     266,2024  63x4          the box, in page coordinates
       line        M 0 2 L 55 2            so 55 = width - 8
       arrowhead   53,12.2  63,2  53,-8.2  a 10-wide, 20.4-tall triangle whose
                                           tip lands on the element's right edge
       stroke      4px, dasharray 4,4      exact 4 on / 4 off
       opacity     0.498

   SECOND CONSUMER OF THIS BLOCK. It is duplicated from css/projects-alere.css
   rather than hoisted, which is the same call that file's header records for the
   quote-mark mask: two consumers is not enough to move a rule into
   components.css. If a THIRD page needs a leader line, that is the point.

   THEY ARE SOLID NOW, and that is a meaning change, not a style one. Owner's
   rule: on this page a DASHED line is the progression of the story, and a SOLID
   line points at something inside a picture. Every one of these twenty-three is
   a pointer into a screenshot or the search-bar illustration, so all of them are
   solid. What stays dashed is the orange arrow off the plate, the swoosh out of
   "So...", and the two connectors between the test stages — see .leader-dashed.

   The dashed pattern is kept in .leader-dashed because a repeating-linear-gradient
   gives it exactly; CSS `border: dashed` does not — its dash length is
   engine-defined and would drift from the arrowheads. The head is a border
   triangle rather than a second gradient because 10 x 20.4 is not a shape a
   gradient can cut.

   WHERE THE OPACITY LIVES DIFFERS IN THE SOURCE and the result is identical:
   the eighteen `compound line` widgets carry `opacity: 0.498` on the element
   with a solid white stroke inside, while the five plain `line` widgets
   (u714/u716/u718/u720/u721) put the alpha in the stroke colour and have no
   element opacity. One rule covers both. */
.leader {
  height: 3px;
  opacity: 0.498;
  background: var(--color-white);
  /* The gradient must stop 8px short so it does not show through the head's
     transparent border edges. Clipped by width rather than by a shorter
     background-size, so the dash phase stays anchored to the LEFT end — which
     is where the source's path starts. */
  background-clip: content-box;
  padding-right: 6px;
  box-sizing: border-box;
}

/* The story lines. Same box, same arrowhead, dashed fill. */
.leader-dashed {
  background: repeating-linear-gradient(
    to right,
    var(--color-white) 0,
    var(--color-white) 4px,
    transparent 4px,
    transparent 8px
  );
  background-clip: content-box;
}

/* Between the three test vignettes, in the gaps their artwork leaves: First
   Impressions inks to 391 and Usage Tests starts at 580; Usage Tests ends at 900
   and Scoring starts at 1113. Both sit at y 5326, the vertical centre of the
   three scenes (5213..5440). */
.leader-stage-1 { left: 411px; top: 5324px; width: 149px; }
.leader-stage-2 { left: 920px; top: 5324px; width: 173px; }

.leader::after {
  content: "";
  position: absolute;
  left: calc(100% - 8px);
  top: 50%;
  width: 0;
  height: 0;
  transform: translateY(-50%);
  border-left: 8px solid var(--color-white);
  border-top: 7px solid transparent;
  border-bottom: 7px solid transparent;
}

/* Rotation is about the element's own centre, which is what the source does
   (`transform-origin: 50% 50%` on every one of them).

   THE FIVE 180deg LEADERS ARE STATED 1px LOWER THAN THE SOURCE. Their widgets
   are 56x6 rather than 56x4, with the path on the box's own centre line at
   y = 3. This box is 4 tall, so its centre is y = 2, and the extra pixel is
   added to the top instead — the drawn line lands on the source's own y either
   way, and the arrowhead (which is centred on the line, not on the box) comes
   with it. */

/* around the original platform */
/* The two vertical ones. They run from the underside of their label (1580, the
   bottom of a 51px line box starting at 1529) down to 1630 — 2px clear of the
   screenshot's top edge at 1632, the same clearance the horizontal leaders keep
   from its left edge. They used to run INTO the picture as far as the control
   they name (1664.5 and 1769.5); the x still identifies the control, the arrow
   no longer lands on it.
   rotate(90deg) is about the box's own centre, so for a vertical run of length L
   centred on (cx, cy):  left = cx - L/2,  top = cy - 1.5. */
.leader-orange      { left: 572px;   top: 1603.5px; width: 50px; transform: rotate(90deg); }
.leader-copy        { left: 863.5px; top: 1603.5px; width: 50px; transform: rotate(90deg); }
.leader-jumbled     { left: 1182px; top: 1675px; width: 56px; transform: rotate(180deg); }
.leader-tabs        { left: 266px;  top: 1707px; width: 63px; }
/* Two additions, both aimed at rows read off the render:
       green "Utilities" panel header   1717.3..1736.7, centre 1727
       "Orders / Customers / Products"  1721.7..1733.3, arrow at 1731 so its
                                        two-line label clears .callout-tabs */
.leader-utilities   { left: 1182px; top: 1725.5px; width: 56px; transform: rotate(180deg); }
.leader-orders      { left: 266px;  top: 1729.5px; width: 63px; }
.leader-crucial     { left: 1182px; top: 1813px; width: 56px; transform: rotate(180deg); }
.leader-duplicate   { left: 1182px; top: 1884px; width: 56px; transform: rotate(180deg); }
.leader-nested      { left: 266px;  top: 1905px; width: 63px; }
.leader-unnecessary { left: 1182px; top: 1995px; width: 56px; transform: rotate(180deg); }
.leader-bold        { left: 266px;  top: 2024px; width: 63px; }
.leader-useless     { left: 1182px; top: 2116px; width: 56px; transform: rotate(180deg); }
.leader-phantom     { left: 423px;  top: 2187px; width: 65px; transform: rotate(270deg); }
.leader-blue        { left: 744px;  top: 2187px; width: 65px; transform: rotate(270deg); }
.leader-green       { left: 997px;  top: 2187px; width: 65px; transform: rotate(270deg); }

/* under the search bar, pointing up into it */
.leader-search      { left: 309px;  top: 3919px; width: 51px; transform: rotate(270deg); }
.leader-context     { left: 674px;  top: 3919px; width: 51px; transform: rotate(270deg); }
.leader-options     { left: 1068px; top: 3919px; width: 51px; transform: rotate(270deg); }

/* around the redesign. The screenshot spans x 327..1178; the left-hand arrows
   tip at 325 and the right-hand ones at 1187, so none of them crosses its edge. */
.leader-switchers   { left: 1187px; top: 4213px; width: 59px; transform: rotate(180deg); }
.leader-icons       { left: 1187px; top: 4248.5px; width: 59px; transform: rotate(180deg); }
.leader-callmech    { left: 209px;  top: 4218px; width: 116px; }
.leader-primary     { left: 209px;  top: 4246px; width: 116px; }
.leader-clutter     { left: 1187px; top: 4358px; width: 59px; transform: rotate(180deg); }
.leader-contrast    { left: 209px;  top: 4372px; width: 116px; }
.leader-nesting     { left: 1187px; top: 4468.5px; width: 59px; transform: rotate(180deg); }
.leader-links       { left: 209px;  top: 4503.5px; width: 116px; }
.leader-clear       { left: 209px;  top: 4551px; width: 116px; }
/* THESE TWO ARE AIMED AT THE LABEL, NOT AT THE BUTTONS. Owner's instruction:
   the top arrow lines up with "Consistent", the lower one with "secondary". The
   source put them on the two things the label names — Submit Order (4622..4667)
   and Create Schedule (4670..4705), 48px apart — but the label is two 17px lines,
   so the two readings cannot both hold. At 4651 and 4668 the pair now straddles
   the divider between the primary button and the secondary ones rather than
   landing one on each. */
.leader-buttons-a   { left: 1187px; top: 4649.5px; width: 59px; transform: rotate(180deg); }
.leader-buttons-b   { left: 1187px; top: 4666.5px; width: 59px; transform: rotate(180deg); }
.leader-adaptive    { left: 209px;  top: 4661px; width: 116px; }

/* ---------------------------------------------------------------------------
   THE JOURNEY — the analysis, the site visits, the model, the prototype
   --------------------------------------------------------------------------- */

.journey-text {
  margin: 0;
  font-size: 19px;
  line-height: 25px;
  color: var(--color-white);
}

.text-analysis  { left: 65px;  top: 2326px; width: 1331px; }
.text-visits    { left: 365px; top: 2812px; width: 668px; }
.text-empathy   { left: 588px; top: 2933px; width: 550px; text-align: right; }
.text-obvious   { left: 435px; top: 3063px; width: 674px; }
.text-learned   { left: 365px; top: 3198px; width: 811px; }
.text-next      { left: 65px;  top: 3320px; width: 1319px; }
.text-context   { left: 65px;  top: 4040px; width: 1319px; }
.text-prototype { left: 65px;  top: 4851px; width: 1319px; }

/* u639's four yellow runs are Kumbh REGULAR 400 against 200 body copy, not the
   Bold that every other <b> on this page is. It is the lightest of the page's
   three bold weights and it is the source's own. */
.text-analysis b { font-weight: 400; }

/* The last line of u639, and the only centred line in any body block on the
   page: 25px, centred in the 1331px box, sitting on its own. The swoosh's tail
   comes out of it. */
.text-analysis .beat {
  display: block;
  font-size: 25px;
  text-align: center;
}

/* u844's lead-in is Kumbh SemiBold 650 — heavier than the page's 700 <strong>
   is light, which sounds wrong and is not: 650 in this variable face renders
   between Medium and Bold, and the source uses it here and on five of the six
   accolade credits. */
/* 600, NOT THE SOURCE'S 650. The fonts are self-hosted static cuts now (see
   base.css), so 650 no longer exists and would snap UP to 700; the owner set
   it to 600 on 2026-09-03, the nearest cut that cannot widen the run and
   wrap a line. The same change is made on .growth-text .heavier below and on
   Alere's accolade credits. */
.text-learned strong { font-weight: 600; }

/* u640 opens with "Next Steps:" at 30px on a 91px line box. That leading is the
   source's own and it is doing a job — it is what puts 61px of air between the
   heading and the paragraph under it, where every other break in the block is a
   25px blank line. Stated as line-height rather than as a margin because that
   is the construction the source's own y-coordinates were laid out against. */
.text-next .lead-in {
  display: block;
  font-size: 30px;
  line-height: 91px;
}

/* u842 — the long dashed swoosh that carries "So…" down into the site-visits
   vignette. Same origin correction as the curved arrow:

       element   442,2543  327x357  ->  centre 605.5, 2721.5
       file      439,2540  344x374  ->  origin 605.5-439, 2721.5-2540
                                                =  166.5, 181.5 */
.swoosh {
  left: 439px;
  top: 2540px;
  width: 344px;
  height: 374px;
  transform: rotate(114.3441291211067deg);
  transform-origin: 166.5px 181.5px;
}

/* ---- the site-visits vignette --------------------------------------------- */

/* u730. Copied verbatim: the aeroplane is one welded silhouette with a
   horizontal #57697c -> #a5b6cb ramp baked into it, and it is not a shape the
   kit has or should have. */
.plane { left: 244px; top: 2812px; width: 72px; height: 72px; }

/* u731..u734 — the four speed trails behind it. The source draws each as a
   1x98 SVG stroked with a vertical #35FF00 -> #41556A gradient; as CSS that is
   a 1x98 box with the same gradient as its background, which is exactly the
   same ink and saves three files.

   All four are rotated 45deg about their own centres, which is what the source
   does. Their lengths are identical; only the origins differ. */
.speed {
  width: 1px;
  height: 98px;
  background: linear-gradient(to bottom, var(--color-accent), var(--color-bg));
  transform: rotate(45deg);
}

.speed-1 { left: 209px; top: 2825px; }
.speed-2 { left: 213px; top: 2857px; }
.speed-3 { left: 223px; top: 2867px; }
.speed-4 { left: 257px; top: 2870px; }

/* ---- the crowd furniture --------------------------------------------------
   Five vignettes on this page put a figure at a screen, and the screen is
   always the same two pieces: a rounded outline and a base bar under it. Both
   are plain rectangles in the source (class box_3), so both are
   <ui-icon name="rect">.

   TWO COLOURWAYS, and they are the source's: white with the page colour behind
   the glass for the three call-centre desks, and #a0aab4 for the projector in
   the Scoring vignette. The page-coloured fill is not decoration — it is what
   hides the crowd standing behind the screen. */
.screen {
  --icon-fill: var(--color-bg);
  --icon-stroke: var(--color-white);
  --icon-stroke-width: 4px;
  --icon-radius: 14px;
}

.screen-base {
  --icon-fill: var(--color-white);
  --icon-radius: 14px;
}

.screen-grey {
  --icon-fill: transparent;
  --icon-stroke: #a0aab4;
}

.screen-base-grey {
  --icon-fill: #a0aab4;
  --icon-radius: 30px;
}

/* The speech LABELS — the ones with words in them, as against the wordless
   <ui-icon name="speech"> bubbles. Grey plates with a triangular tail. */
.bubble {
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2px;
  border-radius: 14px;
  background: #d7d7d7;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 14px;
  line-height: 1.2;
  color: #000;
}

/* The tail. One triangle, traced from the source's own path — 24x27, 29x32 and
   29x32 copies, all the same three vertices as a proportion of the box:

       M 23.750 26.836  L 0 0  L 19.800 0  Z      (24x27)
       -> (98.96%, 99.4%)  (0, 0)  (82.5%, 0)

   .bubble-tail.left is the same shape mirrored, which is exactly what the
   source's other two copies are — their path is
   `M 0.3015 31.806 L 29 0 L 5.075 0 Z`, whose vertices are 100% minus the
   first's, to 0.01%. */
.bubble-tail {
  background: #d7d7d7;
  clip-path: polygon(0 0, 82.5% 0, 98.96% 99.4%);
}

.bubble-tail.left { transform: scaleX(-1); }

/* THE HEADSET IS ONE SHAPE — band, boom and both earcups welded together in
   the kit (`headset` in js/icons.js). It replaced two SVG files, a hand-drawn
   inline arc and six separately positioned earcups; there are now three
   instances of one path and nothing to keep in step between them.

   The MIC BALL stays a separate element on purpose: it is the one piece that
   takes a colour of its own, and on the Results badge that colour is green.

   Each instance is placed by the CUPS' bounding box, which is what the shape is
   authored to — 8px wider than the band on each side. */
.headset { --icon-fill: var(--color-white); }

/* The mic ball. It is the kit's CIRCLE, not a rect with a 50% radius: at 8.5px
   a border-radius circle rasterises with visible flats, and this is the same
   shape the badge draws as an SVG <circle>. Centred on the BOOM'S TIP — the
   band path's own end points, (44.76, 66.40) and (44.76, 69.60) — so the boom's
   squared-off cap ends up inside the ball instead of poking out past it. */
.mic {
  --icon-fill: var(--color-white);
  /* No identity transform. <ui-icon> always sets rotate(var(--icon-rotate, 0deg)),
     and even a 0deg rotation gives the element its own rasterisation context, which
     is what lets a ~9px circle land off the device-pixel grid and come out oval at
     one browser zoom and squared at another. These two never rotate, so the
     transform buys nothing and costs the crispness. Paired with whole-pixel boxes
     in the markup. */
  transform: none;
}

/* u749 — the angry customer's line, the one bubble whose plate is a different
   size and type size from the four in the test vignettes. */
.bubble-shout {
  left: 1133px;
  top: 2885px;
  width: 115px;
  height: 30px;
  font-size: 15px;
}

/* ---------------------------------------------------------------------------
   THE SEARCH BAR — the flattened navigation model
   ---------------------------------------------------------------------------
   Five pieces in the source and five here, in the source's own paint order,
   because the order is what makes it work: the two grey WELLS go down first,
   and the two end caps are laid on top with their glyphs knocked OUT of them.
   What reads as a magnifier and a back-arrow is the well showing through a hole.

   That is why the caps are copied verbatim as SVG rather than rebuilt: the
   knockout is an even-odd hole in a rounded, non-rectangular shape, and as CSS
   it would have to be a mask — which is the case CLAUDE.md says to copy the
   asset for.

   The middle plate is a plain rectangle and IS CSS.

   THE MIDDLE PLATE'S GRADIENT RUNS THE OTHER WAY FROM THE CAPS' and that is the
   source's:

       caps    (76, 0) #F2F2F2  ->  (76, 170) #C0BEBE     light at the top
       plate   (315, 170) #F2F2F2 -> (315, 0) #C0BEBE     light at the BOTTOM

   With a 3px gap either side and a drop shadow on all three, the caps read as
   raised and the plate as inset — a field between two buttons. It is reproduced
   rather than normalised. */

.search-well {
  width: 107px;
  height: 113px;
  background: #c9c9c9;
}

.search-well-left  { left: 278px;  top: 3738px; }
.search-well-right { left: 1035px; top: 3738px; }

/* The two caps. The element is 152x170 at 240/1028, 3709; the artwork file is
   162x180 with the shape drawn at +5,+3 inside it, so the file is placed at
   -5,-3 from the element — the source's own `#u548_img { left: -5px; top: -3px }`.
   Verified against the file's own `<g transform="matrix(1 0 0 1 -235 -3706)">`,
   which is the element's 240,3709 minus exactly that offset. */
.search-cap {
  width: 162px;
  height: 180px;
  filter: drop-shadow(0 2px 2.5px rgba(0, 0, 0, 0.349));
}

.search-cap-left  { left: 235px;  top: 3706px; }
.search-cap-right { left: 1023px; top: 3706px; }

/* u550. 78px Kumbh Regular in #8A8A8A, centred in the plate — the source gives
   its text box `align-self: center` and the paragraph `text-align: center`, and
   the rendered ink confirms it (505px of ink centred in 630 starts at 457.5,
   which is where the original draws it). */
.search-field {
  left: 395px;
  top: 3709px;
  width: 630px;
  height: 170px;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(to top, #f2f2f2, #c0bebe);
  filter: drop-shadow(0 2px 2.5px rgba(0, 0, 0, 0.349));
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 78px;
  line-height: 1;
  color: #8a8a8a;
}

/* ---------------------------------------------------------------------------
   THE REDESIGN — the second annotated screenshot
   --------------------------------------------------------------------------- */

.shot-redesign { left: 327px; top: 4182px; width: 851px; height: 603px; }

/* The three buttons the "Consistent primary and secondary buttons" callout
   points at. They are drawn ON TOP of the screenshot in the source, at the same
   place the bitmap already shows them — a crisp redraw over a scaled-down
   photograph, so the one detail the callout is about stays legible.

   13px is Axure's own default: none of the three widgets states a font size and
   there is no `.text` rule in the export to inherit one from. Measured against
   the rendered original rather than assumed. */
.ui-button {
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 141px;
  border: 1px solid #d4d4d4;
  background: #e3e6e8;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 13px;
  line-height: 1.2;
  color: #0096d7;
}

.ui-button-primary {
  border-color: #797979;
  background: #0096d7;
  color: var(--color-white);
}

.btn-submit   { left: 974px; top: 4619px; height: 51px; }
.btn-create   { left: 974px; top: 4670px; height: 35px; }
.btn-schedule { left: 974px; top: 4703px; height: 35px; }

/* ---------------------------------------------------------------------------
   THE USABILITY TEST — three vignettes and their copy
   --------------------------------------------------------------------------- */

/* u631 / u835 / u836. 35px in the same pale #FFECA9 the action label uses, on
   the source's own 30px leading — which is tighter than the type, deliberately:
   these are one-line stage names, and the short leading is what keeps them
   sitting on the vignette below rather than floating. */
.stage-label {
  margin: 0;
  top: 5140px;
  height: 29px;
  font-family: var(--font-body-light);
  font-weight: 200;
  font-size: 35px;
  line-height: 30px;
  color: #ffeca9;
  white-space: nowrap;
}

.label-impressions { left: 126px;  width: 299px; }
.label-usage       { left: 666px;  width: 234px; }
.label-scoring     { left: 1181px; width: 184px; }

/* The three columns of copy under them. All 19/25, all starting on the same
   top, which is what makes them read as three columns rather than three
   paragraphs. */
.stage-text {
  margin: 0;
  top: 5470px;
  font-size: 19px;
  line-height: 25px;
  color: var(--color-white);
}

.text-impressions { left: 65px;   width: 471px; }
.text-usage       { left: 580px;  width: 486px; }
.text-scoring     { left: 1107px; width: 312px; }

/* u837 — the row of hands holding up scoring paddles, closing the section. Full
   bleed to the 1440 the content bands use, with the same 4px sliver of page
   colour on the right that the hero photograph leaves. */
.scoring-paddles { left: 0; top: 5673px; width: 1440px; height: 321px; }

/* ---------------------------------------------------------------------------
   RESULTS — seven badges beside seven lines
   --------------------------------------------------------------------------- */

/* The two lists the badges sit beside. 120px leading is the source's, and it is
   what sets the whole section's rhythm: the badge centres come out one leading
   apart, to within the few px the source hand-placed them at.

   THE SECOND LIST IS PULLED LEFT FROM THE SOURCE'S 164 TO 153. The badges end
   at x 141, so 153 is an 12px badge-to-text gutter — which is what the first
   list (u848) and the closing note (u874) both use. u882's 164 is a 23px
   gutter, an 11px slip that reads as a misaligned column when the two lists sit
   one above the other. The three now agree; nothing else about them moved.

   No width is stated. These are single-column lists with the whole page to
   their right — the source draws boxes of 795 and 633 and neither is doing any
   work.

   THE LARGE LABEL VARIANT, 26px against the source's 19 — see
   --metric-label-lg in base.css for why there are two and which page takes
   which. Nothing else here moves with it: the 120px line box is the badge
   rhythm, and a row's ink centre shifts 0.35px between the two sizes. The
   longest row inks to 746.3px at 26, so from left 153 it ends at 899 and no
   width is needed to keep it off anything. */
.results-list {
  left: 153px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--metric-label-lg);
  line-height: 120px;
  color: var(--color-white);
}

/* The parenthetical attributions. #FFE073 in the source, and white at 67% here
   — owner's call: they are ancillary text and the yellow gave them the same
   voice as the page's emphasis runs and as the closing line's "1 billion
   dollars", which is the one place that yellow still means something.

   0.67 IS NOT A ROUND NUMBER, IT IS A CONTRAST TARGET. Composited over the
   page's #41556a it computes to 4.50:1, which is WCAG AA for normal-size text
   with nothing to spare — "barely passing", as asked. Full white on this
   background is 7.69:1. Do not nudge it down: 0.62 is 4.11:1 and fails.

   0.7em, NOT A STATED PIXEL SIZE. The colour alone did not separate the
   attribution from the metric it qualifies once the labels went to 26px, so it
   is 70% of whatever size the label is — 18.2px against the large variant,
   13.3px if this page ever took the small one. Relative because the two are one
   sentence: a stated px here would have to be changed again the next time
   --metric-label-* moves, and the whole point of that pair is that a page picks
   one and everything follows.

   THE SIZE DOES NOT RELAX THE CONTRAST TARGET. WCAG's easier 3:1 applies only
   to text at 24px or over (18.66px if bold); at 18.2px regular this is
   normal-size text and still owes the full 4.5:1, which is what 0.67 buys.

   `line-height: 0` IS LOAD-BEARING — without it the first list's rows drift 3px
   further out of line with their badges each row down. The 120px leading is a
   LENGTH, so the smaller run inherits the same 120px box around a 23.1px em
   instead of a 33px one: its half-leading grows, and the box ends up 2.3px
   shallower above the baseline and 2.3px deeper below it than the strut's. A
   line box is max-ascent + max-descent across its inline boxes, so it came out
   122.29 — measured, the three <li> were 123 tall against list B's 120, and row
   3 sat 5px under its badge. Zeroing the leading collapses the run's box to
   nothing while the glyphs still paint, so the strut alone sets the line. Same
   fix, same reason, as .ring-value sup. */
.results-list em { font-size: 0.7em; line-height: 0; color: rgba(255, 255, 255, 0.67); }

.results-list-a { top: 6082px; }
.results-list-b { top: 6438px; }

/* THE THIRD ROW SITS 3px LOWER than its two neighbours. The badges in this list
   are the source's own hand placements and run 3.5-5.5px below their rows'
   centres; on the smiley that shows, because the earcups give the badge a hard
   horizontal axis for the eye to line the text up against. Nudging this one row
   costs nothing — the 120px leading and the other two rows are untouched — and
   it is the row, not the number, that moves: "200,000+ users now enjoy their
   jobs" is a single line and cannot be split. */
.results-list-b li:nth-child(3) {
  position: relative;
  top: 3px;
}

/* u874 — the closing line, which is not a list item: 26px with "1 billion
   dollars" at 40. Its badge is the exclamation mark.

   34px OF LEADING, NOT THE SOURCE'S 42, AND THE TWO ARE THE SAME CHANGE. The
   source shares one baseline between the 26px run and the 40px one, so the big
   run's cap rises 10.3px higher than the small run's beside it and line 2 needs
   that much extra air above it — 42px of leading is paying for a 26px line's
   worth of gap plus the big run's overhang. Top-align the two runs' ink and the
   overhang is gone, so the leading can be an ordinary one: 34 is 1.31, the
   ratio the source uses for its own 19-on-25 copy.

       gap between line 1's ink and line 2's = leading - 25.882
       at 42  16.1px      at 34  8.3px

   Line 1 rises 4px as a consequence (its half-leading shrinks), which puts the
   paragraph's ink centre at 6863.2 against the badge's 6860.5 — 2.7px out,
   where it was 11px out before. */
.results-note {
  left: 153px;
  top: 6826px;
  width: 760px;
  margin: 0;
  font-family: var(--font-body-light);
  font-weight: 200;
  font-size: 26px;
  line-height: 34px;
  color: var(--color-white);
}

/* TOP-ALIGNED TO THE SMALL RUN BESIDE IT, by lowering its baseline exactly the
   difference of the two runs' measured ink ascents:

       "this project was worth"  26px/200   19.280
       "1 billion dollars"       40px/700   29.539
                                            10.259

   Canvas TextMetrics actualBoundingBoxAscent on the real strings, not cap
   heights of an 'H' — though in Kumbh Sans the ascender and the cap are the
   same height, so the two agree to 0.005px here.

   `vertical-align` and not a flex or a translate: the run has to stay in the
   inline flow so the line still wraps and the small run still sits on the
   paragraph's own baseline. (Alere's ring superscripts learned this the hard
   way — a flex item ignores vertical-align outright.) */
.results-note b { font-size: 40px; vertical-align: -10.259px; }

/* ---- the badges ----------------------------------------------------------- */

/* All seven badges are one 77x77 box, so a badge is placed by a single top and
   every part of it is measured from the same centre. The source instead places
   the track and the arc as two separate widgets whose tops and lefts differ by
   1-2px — 66,6106 and 64,6104 — precisely so that their centres agree at
   (102.5, 6142.5). Reproducing two boxes to make one centre would be copying
   the workaround rather than the result.

   Left is 64 (the arc widget's) on six of the seven, so the 77px box spans
   64..141 with its centre on 102.5. The seventh, the 40min badge, states 65 for
   its arc and 67 for its track — centres 103 and 103.5 against every other
   badge's 102.5. It takes 64 with the rest; a column of seven circles that
   disagree by a pixel is hand slop, not composition.

   THE TOPS ARE THE SOURCE'S, INCLUDING ITS OWN DRIFT. The first list's three
   badges centre on their rows exactly (6142.5 against a row centre of 6142, and
   so on). The second list's three sit 5.5, 4.5 and 3.5px low. That is the
   original's hand-placement, it is under 6px on a 77px circle, and it is left
   alone — unlike the left/track slop above, which would have made two circles
   in one column disagree with each other. */
.badge {
  left: 64px;
  width: 77px;
  height: 77px;
}

/* A badge's contents are placed against the BADGE, so the badge moves as one
   thing. .case > * gives absolute positioning to the canvas's own children; its
   grandchildren need their own rule. */
.badge ui-icon,
.badge img { position: absolute; }

.badge-84     { top: 6104px; }
.badge-75     { top: 6224px; }
.badge-10     { top: 6344px; }
.badge-40     { top: 6465px; }
.badge-thumbs { top: 6584px; }
.badge-smile  { top: 6703px; }
.badge-bang   { top: 6822px; }

.ring-art {
  position: absolute;
  inset: 0;
  width: 77px;
  height: 77px;
}

/* THE TRACK. The source strokes a 73px circle 6px wide and clips the stroke to
   the circle — Axure's inner stroke — so what is drawn is a 3px band inside a
   36.5px radius. As a plain SVG stroke that is r 35, width 3. The 0.2 comes
   from the widget's own opacity.

   TWO OF THE FIVE TRACKS ARE A BIGGER CIRCLE AND KEEP IT. The thumbs and the
   smiley have 77px tracks rather than 73px (u850 and u878 against u846, u867,
   u870), so their band sits at r 37 instead of r 35 — 2px further out, flush
   with the arc badges' outer edge instead of inside it. Measured off their own
   paths, not assumed: CLAUDE.md's rule is not to apply one value to five
   without checking each.

   The other two badges — $10 and the exclamation mark — have NO track at all.
   Their ring is a complete green annulus, so there is nothing for a track to
   show. */
.ring-track {
  fill: none;
  stroke: var(--color-white);
  stroke-width: 3;
  opacity: 0.2;
}

.badge-thumbs .ring-track,
.badge-smile .ring-track { r: 37px; }

/* THE ARC. Same construction as Alere's, and the same geometry: the source's
   path is an annulus 8px thick with a 38.5px outer radius, so the centreline is
   r 34.5 at width 8.

   `pathLength="100"` on the circle is what lets the dash be the percentage
   itself — no circumference, no calc, and the number in the markup is the
   number in the copy beside it.

   DIRECTION IS COUNTER-CLOCKWISE FROM TWELVE O'CLOCK, and that is measured, not
   assumed. Walking u871's path, its outer arc runs from a vertex at 0.74deg to
   one at 90deg the long way round — 270.7deg of sweep, which is 75.2% for a
   badge whose number is 75. Clockwise would have put the gap on the left.

   scaleX(-1) reverses an SVG circle's built-in clockwise direction and moves
   its start to nine o'clock; the rotate then carries that start up to twelve.
   The order matters — CSS applies the rightmost transform first.

   THE 84% RING IS DRAWN AT 84, NOT AT THE SOURCE'S 87.3. Measured the same way,
   u868's arc runs 0.74deg to 45.65deg the long way — 314.4deg, which is 87.3%
   against a badge that says 84. The 75% badge is exact and the 70% artwork
   (shared with Alere's own 70% badge, images/projects-alere/u283.svg) is exact,
   so this one is a slip in the original rather than a convention. The
   convention this file follows is Alere's: --pct IS the number in the copy.

   THE 40min BADGE HAS NO PERCENTAGE, so there is nothing to read off the copy.
   It keeps the source's own drawn sweep, which is 70% — the file is literally
   Alere's 70% arc, reused. */
.ring-arc {
  fill: none;
  stroke: var(--color-accent);
  stroke-width: 8;
  stroke-dasharray: var(--pct) 100;
  transform: rotate(90deg) scaleX(-1);
  transform-origin: 38.5px 38.5px;
  transform-box: view-box;
}

/* The number inside the ring. 30px for the figure, and the small run beside it
   at the source's own size — 17px on the two percentages and the dollar sign,
   14px on "min".

   IT IS ONE INLINE RUN, NOT A FLEX CONTAINER, and that is the whole point of
   this block.

   It was `display: flex; align-items: center`, copied from Alere. That makes
   the digits and the small run TWO INDEPENDENT FLEX ITEMS: `vertical-align` is
   ignored on a flex item, each item is centred in the 77px box on its own, and
   the small run then has to be nudged into place by hand. Measured against the
   original, every one of them came out 8-9px too high — the per-cent signs sat
   above the digits' cap height and clipped into the green ring, the dollar sign
   sat above the "1", and "min" floated off the top of "40".

   `line-height: 77px` on a 77px box centres a single line the same way the
   source's `align-self: center` does, and lands on the same number: the digits'
   em box starts at y 19.5 either way. The difference is that everything is now
   in ONE inline formatting context, so the small run can be aligned against the
   digits' baseline rather than against the box.

   CENTRED, where the source hand-nudges each badge with its own left padding
   (12, 12, 12, 0 and 2px). Those constructions are all aiming at the middle and
   missing it by different amounts — the source's own "84%" ink centre lands
   1.15px left of the box centre. Centring hits what they were aiming for and
   makes the five agree. */
.ring-value {
  position: absolute;
  inset: 0;
  text-align: center;
  line-height: 77px;
  white-space: nowrap;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 30px;
  color: var(--color-white);
}

/* THE SMALL RUN TOP-ALIGNS WITH THE DIGITS AND HANGS OUTSIDE THEM.

   Owner's call, and it is Alere's intent — but Alere's arithmetic never reached
   the glyph, because `.ring-value` was `display: flex` there and still is: a
   flex item ignores `vertical-align`, so the sign was centred in the 77px box
   on its own and then nudged by a number that assumed a shared baseline. It
   landed ~8px above the digits' cap. This block is that intent implemented in
   an inline context, where the number does what it says.

   TOP-ALIGNED. The raise is the difference of the two cap heights, from canvas
   TextMetrics `actualBoundingBoxAscent` so the metrics are not integer-rounded:

       "84"  Kumbh Sans 400 @30px   22.412        "%"  200 @17px   12.617
                                     raise 9.795
       "10"  Kumbh Sans 400 @30px   22.412        "$"  200 @17px   13.447
                                     raise 8.965

   The two differ because the dollar sign is a taller glyph than the per-cent
   sign at the same size — it carries the stroke through above and below the
   O — so one value would not top-align both. 9.795 is also the figure Alere's
   own comment derives, which is the check that this is the same intent.

   HANGING. `width: 0` takes the sign out of the line's width, so the DIGITS
   centre on the ring and the sign sits outside them — "closer to the right side
   of the circle so the number is closer to the middle", which is the owner's
   own description of what it is for. The dollar hangs the other way because it
   comes first: same `width: 0`, plus a `left` of its own advance so it paints
   to the LEFT of the digits instead of over them. */
.ring-value sup {
  display: inline-block;
  width: 0;
  vertical-align: 9.795px;
  position: relative;
  font-family: var(--font-body-light);
  font-weight: 200;
  font-size: 17px;
  line-height: 0;
}

/* 8.727px is the dollar's own advance at 17px Kumbh Thin, measured the same
   way; it is what moves the painted glyph off the digits without moving the
   digits, since `width: 0` has already taken it out of the layout. */
.ring-value sup.pre {
  vertical-align: 8.965px;
  left: -8.727px;
}

/* "min" IS THE ONE SMALL RUN THAT DOES NOT HANG. Three letters at 14px are
   22.6px of advance against the per-cent sign's 14.8 — hung outside the digits
   it runs past the ring entirely. It keeps its width and its own baseline, and
   the whole "40min" is placed from the RIGHT instead:

     margin-left  2px   the owner's gap. Without it the "m" sits against the
                        "0", because the digits carry the source's -1.1px
                        letter-spacing and it closes the natural sidebearing.
     .badge-40    the run is right-aligned in the badge and padded off the
                  edge so the unit clears the grey ring by 2px — see below. */
.ring-value sup.unit {
  width: auto;
  vertical-align: 5.66px;
  font-size: 14px;
  letter-spacing: -0.6px;
  /* -1, where the gap between the two advance boxes used to be 2. "min" is
     placed from the badge's right edge and comes last in the run, so it does
     not move; shrinking this gap pulls the DIGITS right by 3px, which is the
     owner's "move 40 3px closer to min". Ink gap 2.25 -> nominal. */
  margin-left: 0px;
}

/* u847 states -1.1px on its digits, the only badge that does. It is what fits
   "40" and a three-letter unit inside one 61px opening.

   PLACED FROM THE RIGHT, not centred, because that is the edge the owner set it
   against: "min" is to clear the grey ring by 2px, and the digits follow it.
   The 6.54px is solved, not tried:

       ring inner edge         r 33.5, so at the unit's mid-height (y 38.34)
                               it is at x 72.0
       target ink right        72.0 - 2  =  70.0
       ink sits behind the     0.46px — measured with TextMetrics, the "n"'s
       advance by                right sidebearing net of the -0.6 spacing
       target advance right    70.46
       padding-right           77 - 70.46  =  6.54

   The digits land at 12.18, which clears the ring on that side by 7.2. */
/* ---- owner's per-badge nudges, all in painted pixels -----------------------
   Each of these moves ONE thing and is stated as the move the owner asked for.
   `left` on the sup is paint-only (`position: relative`), so the digits cannot
   be dragged along by it; `padding-left` on the value shifts the whole centred
   run by half its value, so a 2px pad is a 1px move.

     .badge-84   % 4px closer to the digits; the digits do not move
     .badge-75   % 1px closer to the digits AND the digits 1px closer to it
                 (pad 2 = run +1, then the sup takes -2 for a net -1)
     .badge-10   the DIGITS' INK centred on the circle. Their advance box was
                 already centred, but "1" carries a wide left sidebearing, so
                 the ink centre sat at 37.92 against the badge's 38.5. A 1.16px
                 pad moves the run 0.58 and lands the ink on centre. */
.badge-84 .ring-value sup { left: -4px; }

.badge-75 .ring-value { padding-left: 2px; }
.badge-75 .ring-value sup { left: -2px; }

.badge-10 .ring-value { padding-left: 1.16px; }

.badge-40 .ring-value {
  letter-spacing: -1.1px;
  text-align: right;
  padding-right: 6.54px;
}

/* u876 — the exclamation mark, Kumbh Black 900 at 53px. */
.badge-bang .ring-value {
  font-family: var(--font-body-black);
  font-weight: 900;
  font-size: 53px;
}

/* ---- the five thumbs ------------------------------------------------------ */

/* A raised thumb is TWO pieces in the source and stays two here: the hand
   (<ui-icon name="thumb">) and a small green cuff below the wrist
   (<ui-icon name="rect">). They are not welded, because the cuff sits at a
   different offset on all five copies.

   THESE ARE THE SAME TEN OFFSETS ALERE USES, to the pixel — the source's badge
   origin here is 64,6584 and there 68,6166, and subtracting each gives the same
   table both times. Axure duplicated one badge across the two pages. */
.thumb-hand,
.thumb-cuff { --icon-fill: var(--color-accent); }

.thumb-1-cuff { left: 9px;  top: 27px; --icon-width: 4px;  --icon-height: 12px; }
.thumb-1-hand { left: 13px; top: 20px; --icon-width: 15px; --icon-height: 19px; }
.thumb-2-cuff { left: 42px; top: 32px; --icon-width: 5px;  --icon-height: 13px; }
.thumb-2-hand { left: 46px; top: 25px; --icon-width: 17px; --icon-height: 20px; }
.thumb-3-cuff { left: 18px; top: 49px; --icon-width: 5px;  --icon-height: 13px; }
.thumb-3-hand { left: 22px; top: 42px; --icon-width: 17px; --icon-height: 20px; }
.thumb-4-cuff { left: 36px; top: 14px; --icon-width: 3px;  --icon-height: 10px; }
.thumb-4-hand { left: 39px; top: 9px;  --icon-width: 12px; --icon-height: 15px; }
.thumb-5-cuff { left: 45px; top: 55px; --icon-width: 3px;  --icon-height: 10px; }
.thumb-5-hand { left: 48px; top: 50px; --icon-width: 12px; --icon-height: 15px; }

/* ---- the smiley ----------------------------------------------------------- */

/* Three stroked arcs, copied verbatim: an arc's ends and its curvature are a
   path, not a box, so there is nothing for CSS to build them out of.

   Badge-relative, like the thumbs — the source's page coordinates minus the
   badge's own origin at 64,6703:

       eye left    84,6721 13x4   ->  20,18    rotate 345deg
       eye right  109,6721 13x4   ->  45,18    rotate  15deg
       mouth       75,6737 55x22  ->  11,34    rotate 180deg

   Each file is 4px larger than its element in both axes and offset -2,-2, so
   the eyes' file centre and element centre coincide exactly and 50% 50% is
   correct for them. The mouth's file is 60x27 against a 55x22 element, which
   puts its own centre half a pixel off the element's, so its origin is stated:

       element centre  102.5, 6748     file origin  73, 6735
       origin          29.5, 13 */
/* THE FACE — redrawn, not the source's. The two arcs-and-a-grin the earlier
   pass built out of the source's own eye and mouth files read as a cheesy
   smiley; this is the contented version the owner asked for: the eyes are
   shallower and set further apart, and the mouth is a wide, soft curve rather
   than a deep grin. Round caps, drawn in badge coordinates so it needs no
   scaling wrapper — its widest ink is r 21.7 against the grey ring's inner
   edge at 30. */
.smile-face {
  position: absolute;
  inset: 0;
  width: 77px;
  height: 77px;
  max-width: none;
  fill: none;
  stroke: var(--color-bg);
  stroke-width: 3.4;
  stroke-linecap: round;
}

/* ---- the headset on the smiley badge ---------------------------------------

   OWNER'S ADDITION — the original has no headset here. These are call-centre
   workers, so the face that says "200,000+ users now enjoy their jobs" wears
   the one the three vignettes above put on them.

   IT GOES AROUND THE GREY CIRCLE, IN WHITE. The circle is the head; the band is
   a separate ring outside it with 1.5px of page between them, exactly as the
   vignettes separate the band from the grey disc it sits on. An earlier pass
   made the track ring itself do the headband's job, in the track's own faint
   white — that read as a diagram of a headset rather than as one, and it is not
   what the badge needed.

   IT THEREFORE REACHES OUTSIDE THE 77px BADGE, and that is deliberate: a head
   plus a band around it plus earcups around that cannot fit a box the head
   already fills. The badge box, the track ring and every other badge's
   geometry are untouched — only this one's artwork overhangs, by 6.5px each
   side and 4.6px below. Measured against what is beside it: the row's copy
   starts at page x 153 and the right earcup ends at 147.5, so the clearance is
   5.5px. The source's own badge-to-text gutter is 12, and nothing else on this
   page comes closer.

   The proportions are the vignettes' own, taken relative to the band radius and
   fitted to the space rather than scaled from one dimension:

       band            centreline r 39.5, 3px stroke   -> outer 41
       grey circle     outer 36.5                       -> 1.5px of clearance
       earcups         11 x 26, straddling the band     -> outer r 45
       mic ball        r 5.5 at 162 degrees clockwise from twelve, which is
                       where the source hangs it (its ball sits at 1.02x the
                       band radius, 17.7 degrees off six o'clock)
       band gap        the arc runs 240 degrees clockwise round to 162, leaving
                       the bottom-left open — the source's own opening

   THE SMILEY IS BACK AT FULL SIZE. It was scaled 0.88 while the earcups sat
   inside the ring and crowded its mouth; with them outside, the mouth clears
   the nearer cup by 4.5px and the further one by 3.5. */

/* `max-width: none` is not optional. base.css gives every <svg> and <img>
   `max-width: 100%`, and 100% of the 77px badge would clamp this 101px box to
   77 — the viewBox then scales to fit and the band lands INSIDE the grey circle
   instead of around it, at 0.762 of its stated radius. Same trap as
   `.cluster img` further up this file, and it looked like a geometry error
   rather than a CSS one. */
/* THE BADGE'S HEADSET is the same kit shape at the SOURCE's own proportions,
   which is what makes this badge and the two vignettes read as one object.
   Everything below follows from one constraint and one ratio:

     constraint   the row's copy starts at page x 153 and the badge at 64, so
                  the assembly can be 94 wide at most (right edge 149.5, a 3.5px
                  gap). That fixes the scale: 94/87 of the authored shape.
     ratio        the source's head is 55 across against a 71 band, so the head
                  follows at 0.7746 of the band's outer diameter -> r 29.7.

   The head was r 33 while the band was hand-drawn; taking the source's ratio
   shrinks it slightly and gives back a 5.3px gap to the band's inner edge,
   which is the separation the owner set by eye when the band was mine.

   Placed so the BAND's centre — x 43.5, y 35.38 of the authored 87x70 — lands
   on the badge's own centre. */
.smile-headset {
  left: -7.04px;
  top: 0.29px;
  --icon-width: 91.08px;
  --icon-height: 75.6px;
}

/* GREEN, AND ON TOP. It is drawn after the headset, so it covers the boom's end
   instead of the boom running on into the head. Its centre is the source's own
   (0.2833r, 0.8893r off the band's centre) at this badge's band radius of
   38.35, and its diameter scales with the band the same way. */
.smile-mic {
  position: absolute;
  inset: 0;
  width: 77px;
  height: 77px;
  max-width: none;
  overflow: visible;
  fill: var(--color-accent);
}

/* THE GREY CIRCLE IS SMALLER ON THIS BADGE ONLY, and it is the one badge whose
   ring is not the column's 35. The owner's 3px buffer sets it: the strap's
   inner edge is at r 38, so the grey circle's outer edge goes to 33 and its
   centreline — the ring is stroked 3 — to 31.5, which is 5px of buffer after a
   second shrink at the owner's request. It is also the one track on the page
   painted SOLID white rather than white at 20%: on this badge the ring is the
   head, not chrome, and the headset around it carries the grey instead.
   Concentric with the strap, as
   both are drawn about (38.5, 38.5); the strap's bounding box looks 1px high
   only because its arc is open at the bottom-left. */
/* THE HEAD. A filled disc in the same #57697c -> #a5b6cb ramp the three
   vignettes light their heads with, so this badge's worker is made of the same
   material as the ones in the story above it — which is what the owner's
   reference image shows.

   IT REPLACED A WHITE RING AROUND A DARK FACE, and that is the point of the
   change rather than a detail of it: a white circle enclosing the page's dark
   background with a wide green mouth across it read as blackface. A lit disc
   with the features knocked out of it in the page's own colour cannot.

   r 33 is the old ring's outer edge, so the head keeps exactly the silhouette it
   had and the 5px buffer to the strap's inner edge at 38 is unchanged. The
   outline that used to sit here is commented out in the markup, and the rule
   that sized it went with it. */
.smile-head { fill: url(#oracle-dome); }

/* ---------------------------------------------------------------------------
   ACCOLADES — six quotes
   ---------------------------------------------------------------------------
   The source's construction is a band rectangle with a text box and a pair of
   quote marks laid on it, and the three are in lockstep on all six: the text is
   129px right of the band and 46px down, and the marks are 84px left of the
   text and 10px up. Those are the same two offsets Alere's six use, so the
   shared rules below are the same rules — a quote is placed by ONE coordinate.

       band 1   66,7113 852     band 4  482,7607 921
       band 2  729,7301 711     band 5  143,7837 934
       band 3   59,7468 680     band 6  847,8000 530

   SET AT THE TESTIMONIALS PAGE'S SIZES — owner's change, carried over from
   Alere. Four of the six are a display quote in the source (26/30); the other
   two are already 19/30. All six are now:

       quote      19px / --line-height-body (22.5)
       credit     20px / --line-height-body, Kumbh Thin 200
       dash       one em dash + nbsp   ("—&nbsp;"), not the source's two en
                  dashes and a space

   Heights are not stated at all: the band is padding around its own content, so
   it is exactly as tall as the quote in it.

     vertical   24 top and bottom, against the source's 46 / varies
     left       80 to the quote, against 129. The marks hang 53.9 left of the
                quote, so this leaves 26px of band outside the mark ink.
     right      60, against the source's 11..247 (it varies per block, because
                each band was drawn by hand)

   <figure> carries a UA margin of 1em 40px. Absolute positioning does not
   remove it — it offsets the box from the left/top it was given. Zeroed.

   The offset is padding rather than an absolutely-positioned inner box because
   the <figcaption> has to FOLLOW the quote, and how far down it starts depends
   on how many lines that quote takes; figcaption must stay a direct child of
   figure, so there is nowhere to wrap the two together. */
.accolade {
  margin: 0;
  padding: 24px 60px 24px 80px;
  /* Stated once, from the quote's own width plus that padding, so the band and
     the text it wraps can never be given two different ideas of how wide the
     block is. .page is border-box (base.css sets it on *), so this width
     INCLUDES the 140px of padding. */
  width: calc(var(--quote-w) + 140px);
  /* The band. White 4.3% fading to nothing, the fade starting at 67% of the
     width — the source's six gradients are 476.37/711, 455.6/680, 617.07/921,
     355.1/530, 625.78/934 and 570.84/852, every one of which is 67.0%. The same
     figure as the alternating bands on Collaboration, Process, Testimonials and
     Alere, which is not a coincidence: it is one Axure style. */
  background: linear-gradient(
    to right,
    rgba(255, 255, 255, 0.043) 0,
    rgba(255, 255, 255, 0.043) 67%,
    rgba(255, 255, 255, 0) 100%
  );
}

/* `position: relative` only so the quote marks have something to hang off —
   the block's own placement comes from the figure's padding. */
.accolade blockquote {
  position: relative;
  margin: 0;
  width: var(--quote-w);
}

.accolade p {
  margin: 0;
  font-family: var(--font-body);
  font-weight: var(--font-weight-body);
  font-size: 19px;
  line-height: var(--line-height-body);
  color: var(--color-white);
}

/* Quote 6 is two sentences the source sets as two consecutive <p>s with no
   blank <p> between them — "You pulled off a miracle! / Nicely done!" is one
   person saying one thing over two lines, so they get no gap. That is the same
   call Alere's quote 3 records, and the source agrees with it both times. */

/* ONE BLANK LINE before the credit, which is Testimonials' rule. The source's
   own gap is a 13px blank <p> — 16px — which at 22.5px leading would sit the
   credit CLOSER to the quote than the quote's own lines sit to each other. */
.accolade figcaption {
  margin-top: var(--line-height-body);
  font-family: var(--font-body-light);
  font-weight: 200;
  font-size: 20px;
  line-height: var(--line-height-body);
  color: var(--color-white);
  /* The credit is one phrase and never breaks. The block widths below are sized
     so it cannot overflow — see --quote-w. */
  white-space: nowrap;
}

/* The speaker's role. The source sets it in Kumbh SemiBold 650 and warm yellow;
   this is the cool blue at the credit's own weight instead — owner's call, and
   it drops both of the source's emphases, the colour and the weight.

   All six credits take this one colour and NONE of them is a link. The named
   speaker (Erin Staudt, quote 1) used to be a LinkedIn link in the cool blue,
   with an underline on hover; the owner removed the link on 2026-09-03 so this
   page matches Testimonials, where no credit links anywhere either. The
   `.who-link` rules that styled it are gone with it. */
.accolade .who {
  color: var(--color-accent-cool);
}

/* NO RULE FOR QUOTE 1'S EMPHASIS, because there is no emphasis left to style.
   Owner's call, arrived at in three steps — the colour went, then the weight,
   then the <b> and <em> themselves. The words the source lifted are recorded in
   a comment beside the quote in projects-oracle.html, which is the only place
   they survive now. Nothing in this section holds a <b> or an <em> any more. */

/* Erin Staudt's quote is also on about-testimonials.html, from the same source
   text. The two differ in one place and it is the ORIGINAL that differs from
   itself: this page's widget says "Senior Technical Product Manager" and the
   Testimonials page's says "Sr.". Each is its own source's own string. */

/* NO `.accolade b` WEIGHT RULE ANY MORE, and this note is here so it does not
   come back. Quote 1's heavy run was Kumbh ExtraBold 900 in the source —
   heavier than the 700 this page's <b> is everywhere else, and the only 900 on
   the page — and it used to be stated here. Quote 1 held the section's only
   <b>, so once that emphasis was dropped the rule had no consumer at all, and
   the <b> is now gone from the markup too.

   WORTH KEEPING IN MIND IF A SIMILAR OVERRIDE IS EVER NEEDED: `.accolade b` and
   `.accolade-1 b` are both specificity (0,1,1), so the later one wins on file
   order alone. This rule sat BELOW the override, which is why the first attempt
   at removing the bold changed nothing. Deleting the rule was the fix that does
   not depend on where in the file anything sits. */

/* THE QUOTE MARKS — the owner's change, carried over from Alere number for
   number. The glyph is the same file the Testimonials page uses, which is in
   fact ALERE's artwork (u473/u474), filed under about-testimonials only because
   that page consumed it first.

   The source draws them here at 21x21 + 21x22, full size, in solid #35FF00.
   They are now:

       scale     62%      box 59x39 -> 36.6 x 24.2
       colour    --color-accent-cool at 0.5
       offset    the source's own mark-vs-text offset (-84 x, -10 y), plus the
                 -3,-3 that cancels the file's rotation slack, all x 0.62:
                     x  (-84 - 3) x 0.62  =  -53.9
                     y  (-10 - 3) x 0.62  =   -8.06  ->  -8

   THIRD CONSUMER of this artwork. about-testimonials.css and
   css/projects-alere.css both carry their own copy of this mask, and that file
   said the third was the point to hoist it into components.css. It is not
   hoisted here, deliberately and with a cost noted: doing it would touch a
   shared stylesheet and require both existing consumers to be re-verified,
   which is a change to make on its own and not inside a page port. It is the
   first item in this page's handoff.

   mask-size MUST be stated — the `mask` shorthand would reset it to the file's
   intrinsic 59x39 and the glyph would be clipped by the smaller box instead of
   scaled into it. */
.accolade blockquote::before {
  content: "";
  position: absolute;
  left: -53.9px;
  top: -8px;
  width: 36.6px;
  height: 24.2px;
  background-color: var(--color-accent-cool);
  opacity: 0.5;
  -webkit-mask-image: url(../images/about-testimonials/quote-marks.svg);
  mask-image: url(../images/about-testimonials/quote-marks.svg);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: contain;
  mask-size: contain;
}

/* ---- placement -------------------------------------------------------------

   THE STAGGER IS THE SOURCE'S; THE DENSITY IS NOT.

   Horizontally nothing has moved: every block still starts its text on the
   source's own x — 195, 858, 188, 611, 272, 976 — so the left-right rhythm the
   original composed is untouched. `left` is that x minus the 80px padding.

   WIDTH. Two of the six quotes are already 19px in the source (blocks 1 and 2,
   u694 and u649), so their widths carry over unchanged and they break into the
   same lines. The other four are 26px, and scaling by 19/26 = 0.731 keeps each
   breaking into the same number of lines it broke into at 26:

       block   source   x 0.731   credit ink   used
         1       640      —          451.9      640
         2       571      —          496.9      571
         3       541     395.4       501.9      508
         4       666     486.8       490.0      496
         5       725     530.0       490.0      530
         6       357     260.9       234.8      261

   The credit figures are measured with a Range over the rendered figcaption on
   the settled page, not estimated from a probe span. Blocks 3 and 4 are where
   the credit wins — 3's quote wants 395 against a 502 credit, and 4's scaled
   486.8 was 3.2px SHORT of its own 490 credit and overflowed. Both take the
   credit's width plus ~6: a caption ending on the content edge to 0.0px is not
   a fit, it is a coincidence waiting for a font metric to change.

   BLOCK 2 IS THE ONE WIDTH ON THE PAGE THAT IS NOT DERIVED FROM THE SOURCE.
   Its text starts at 858 and its quote is 571 wide, so the formula's band would
   run 778..1489 and hang 45px off a 1444 canvas — .page would not clip it,
   .case is `width: 100%`, and the document's scrollWidth would grow. The
   source's own band ends at 1440 because its right padding is 11px rather than
   60. The band is clamped to 666 here, which puts its right edge on 1444 and
   leaves 15px of padding — close to the source's own 11, and the quote inside
   it is untouched.

   VERTICAL. The source's band tops are 7113, 7301, 7468, 7607, 7837, 8000 —
   gaps of 188, 167, 139, 230, 163 against bands of 248, 227, 170, 219, 223,
   which is what makes the blocks overlap and read as clippings laid down rather
   than as a list.

   THE GAPS ARE THE SOURCE'S OWN, SCALED BY EACH BAND'S SHRINK — not re-derived
   from a clearance rule the way Alere's are. That is a deliberate difference
   from Alere and it is worth spelling out, because Alere's own file presents
   the derivation as the method:

       Alere's blocks are 316..452 wide in a 1444 canvas, so its stagger keeps
       adjacent blocks apart HORIZONTALLY and the only thing a vertical rule has
       to protect is the band tint. This page's blocks are 401..780 wide. Ten of
       the fifteen pairs share horizontal range even after the quote marks are
       counted in, so packing to the tint rule alone puts ink on ink: derived
       that way, block 3's credit ran straight through block 4's first line and
       block 5's second line through block 4's credit. Measured on the rendered
       page, not predicted — the arrangement was built, screenshotted, and
       thrown away.

   So the source's rhythm is scaled instead, which preserves the composition it
   was drawn with, and then ONE gap is corrected:

       gap   source   x band shrink        scaled
       1->2    188    x 183/248 = 0.738     139
       2->3    167    x 161/227 = 0.709     118
       3->4    139    x 116/170 = 0.682      95
       4->5    230    x 161/219 = 0.735     169
       5->6    163    x 161/223 = 0.722     118

   THE 1->2 GAP IS 167, NOT THE SCALED 139. At 139 the blocks' ink overlaps by
   4px: block 1's credit ends at 7272 and block 2's quote MARK starts at 7268.
   The mark is what binds, not the text — it hangs 53.9px left of the quote and
   8px above it, which is exactly the 31px of horizontal range these two share
   (block 1 inks to 835, block 2's mark starts at 804). 167 puts 24px between
   them, which is the band's own padding.

       block   band     top      gap    against
         1     183     7113       -
         2     161     7280     167     overlaps 1 by 16, ink clears by 24
         3     116     7369      89     clears 1 by 97, overlaps 2 by 72 *
         4     161     7493     124     clears 3 by 8, clears 2 by 52
         5     161     7662     169     clears 3 by 177, clears 4 by 8
         6     138     7780     118     clears 4 by 126, overlaps 5 by 43

       * blocks 2 and 3 share no horizontal range at all — 3 ends at 756 and 2
         starts at 778 — so their bands can pass each other freely. It is the
         one pair on the page for which the vertical figure means nothing.

   BLOCK 3 IS 29px ABOVE ITS SCALED POSITION (7369, not 7398), which makes the
   2->3 gap 89 and the 3->4 gap 124 rather than the scaled 118 and 95. Owner's
   call, and it is the ONE overlap on this page that was too much: 3 and 4 share
   225px of horizontal range (531..756) and at 7398 their bands overlapped by
   21px right where that range is, so the two tints stacked into a third, darker
   step that read as a rendering fault rather than as one clipping laid over
   another. 7369 puts 8px between them. Every other overlap here is the
   source's own and stays — including 1->2's 16px, which sits where the blocks
   barely share range and reads as intended.

   Every pair that shares horizontal range and is NOT adjacent clears by at
   least 52px, so no two 4.3% bands ever stack; every pair whose ink shares
   horizontal range clears by at least 19px of ink. Both checked in the browser
   against the rendered boxes, not against these numbers.

   The section spans 805px (7113..7918) against the source's 1090. Growth
   Mindset follows it up; see .growth-head. */

.accolade-1 { left: 115px; top: 7113px; --quote-w: 640px; }
.accolade-2 { left: 778px; top: 7280px; --quote-w: 571px; width: 666px; }
.accolade-3 { left: 108px; top: 7369px; --quote-w: 508px; }
.accolade-4 { left: 531px; top: 7493px; --quote-w: 496px; }
.accolade-5 { left: 192px; top: 7662px; --quote-w: 530px; }
.accolade-6 { left: 896px; top: 7780px; --quote-w: 261px; }

/* ---------------------------------------------------------------------------
   GROWTH MINDSET
   --------------------------------------------------------------------------- */

/* The head with the hole, beside the heading — the same artwork the original
   puts on all four project pages (images/projects-access/u208.png), already in
   this rebuild as images/components/head.svg + head-gears.svg with .head-figure
   to size it. See css/projects-alere.css for how that bitmap was taken apart;
   nothing about the asset changed here, this page is its second consumer.

   IT SITS BETWEEN THE TWO TITLE STRINGS — owner's change, and the source has
   exactly the collision here that it has on Alere: it puts the head at x 361,
   which is ON "What I learned:". That string starts at 389 and the head spans
   361..465, so the artwork covers its first 76px. In the original the head is a
   white silhouette at low alpha and the words read through it; here it reads as
   a collision.

   The gap between the strings is opened up to hold it and the head is centred
   in that gap — the same 24px either side, and therefore the same 314 and the
   same 152 that Alere arrived at, because both pages set the same string at the
   same size from the same x. See .section-title .aside for the arithmetic.

   THE WHOLE SECTION MOVES UP 285px from the source, because the Accolades above
   it lost that much when their type came down to the Testimonials sizes. The
   three pieces keep the SOURCE's own spacing between themselves, so nothing
   here is chosen — every number follows from the accolades' measured bottom:

       accolades end   7918    (block 6: top 7780 + its 138px band)
       + 58            7976    the source's own accolades-to-head gap
                               (its 8261 against an accolades end of 8203)
       head            7976
       + 54            8030    title row   (source: 8315 - 8261)
       + 84            8114    body copy   (source: 8399 - 8315) */
.growth-head {
  left: 314px;
  top: 7976px;
  --head-width: 104px;
}

/* The opening's own colour — the disc the gears turn on. */
.growth-head .head-slot {
  background: var(--color-bg);
}

/* The gear plate fills the slot exactly: head-gears.svg is authored in the
   SLOT's coordinate space (viewBox 405x388, which is the 75.28% x 62.38% that
   components.css gives the slot), so it needs no offset of its own and the
   slot's overflow does the masking. */
.growth-head .head-gears {
  width: 100%;
  height: 100%;
}

/* u562, RESET TO THE SITE'S BODY CONVENTIONS rather than the source's — owner's
   change carried over from Alere, and the point of it is that this page should
   read like the rest of the rebuild rather than like the export.

   The source is 19px on 25px leading with a blank 19px line between lessons, so
   each paragraph break costs 25px. What the two long-form About pages do, and
   what this now does:

       size            19px                    unchanged
       leading         --line-height-body      22.5px   (base.css)
       paragraph gap   30px                    the figure css/about-collaboration.css
                                               and css/about-approach.css both use */
.growth-text {
  left: 64px;
  top: 8114px;
  width: 1323px;
  margin: 0;
  font-size: 19px;
  line-height: var(--line-height-body);
  color: var(--color-white);
}

.growth-text p { margin: 0; }
.growth-text p + p { margin-top: 30px; }

/* The lead-in to each lesson. 500 here — Kumbh Medium — because that is what
   the source says: five of the seven lessons open at 500, against Alere's 700
   and Collaboration's and Process's 900. Same colour, same job, two weights
   lighter. */
.growth-text b,
.growth-text strong { font-weight: 500; }

/* Two runs the source sets heavier than the lead-ins: 650 on "irrefutable
   results." and 700 on the last two. They are the payoff lines of their
   paragraphs and the original gives them the extra weight, so they keep it.
   650 is 600 here for the reason given on .text-learned strong above: the
   static cuts have no 650, and 600 is the side that cannot wrap. */
.growth-text .heavier { font-weight: 600; }
.growth-text .heaviest { font-weight: 700; }

/* And one it sets LIGHTER: "in a familiar context" is Kumbh Regular 400 — a
   half-step above the 200 body copy rather than the lead-ins' 500. It is the
   fourth weight in one paragraph, which is the source's own doing. */
.growth-text .lighter { font-weight: 400; }

/* ---------------------------------------------------------------------------
   The page's own paint server, declared in the HTML as a real <svg><defs>
   because an SVG fill cannot take a CSS gradient. Positioned out of flow the
   same way components.css positions the kit's own #kit-defs.
   --------------------------------------------------------------------------- */
.page-defs { position: absolute; width: 0; height: 0; }
