/* PIM-TNG final consolidation — pass 5
   Latest brand icons, natural heading wrapping, and case-study intro layout. */

/* Headings should stay on one line whenever the layout actually has room.
   Earlier passes used character-width caps and balanced wrapping that forced
   visual line breaks even on wide screens. Keep the 50px H1 ceiling, but let
   the containing grid decide when wrapping is truly necessary. */
h1, h2, h3,
.pim-h1, .pim-h2, .pim-h3,
.pim-study-headline,
.pim-flow-headline {
  max-width: none !important;
  max-inline-size: none !important;
  white-space: normal !important;
  text-wrap: wrap !important;
}

.pim-h1 {
  font-size: clamp(38px, 4.2vw, 50px) !important;
}

.home-hero .pim-flow-payoff .pim-h1,
.site-page--features .feature-page-hero .pim-h1,
.consult-page > .pim-pagehero .pim-h1,
.site-page--agent .agent-page-hero .pim-h1,
.security-page > .page-hero .pim-h1,
.site-page--pricing .pim-pagehero .pim-h1,
.site-page--cases .pim-pagehero .pim-h1 {
  max-width: none !important;
  max-inline-size: none !important;
  font-size: clamp(40px, 4vw, 50px) !important;
}

/* Keep prose readable without using the heading itself to constrain width. */
.page-hero-copy > .pim-lede,
.page-hero-copy > .pim-hero-support,
.section-intro > .pim-lede,
.section-intro > p {
  max-width: 74ch;
}

/* Case studies: product first, intro copy to the right, full study below. */
.site-page--cases .case-detail > .case-intro-split {
  padding-block: clamp(42px, 5vw, 72px);
  border-bottom: 1px solid #d6e2eb;
  background: #f5f8fb;
}

.site-page--cases .case-intro-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(360px, .92fr);
  gap: clamp(34px, 5vw, 76px);
  align-items: center;
}

.site-page--cases .case-intro-media {
  min-width: 0;
}

.site-page--cases .case-intro-media .editorial-media {
  margin: 0;
  padding: 0;
  overflow: hidden;
  border: 1px solid #cad9e4;
  border-radius: 4px;
  background: #eef4f8;
  box-shadow: 0 14px 34px rgba(5, 34, 56, .08);
}

.site-page--cases .case-intro-media .editorial-media > img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  max-height: none;
  object-fit: contain;
  border: 0;
  background: #f8fafc;
}

.site-page--cases .case-intro-media .editorial-media > figcaption {
  margin: 0;
  padding: 8px 12px 9px;
  border-top: 1px solid #d8e4ec;
  background: #fff;
  color: #637789;
  font-size: 11px;
}

.site-page--cases .case-intro-media .editorial-gallery {
  display: flex;
  gap: 7px;
  margin: 0;
  padding: 8px;
  overflow-x: auto;
  border-top: 1px solid #d8e4ec;
  background: #eef4f8;
}

.site-page--cases .case-intro-media .editorial-gallery figure {
  flex: 0 0 124px;
  margin: 0;
}

.site-page--cases .case-intro-media .editorial-gallery img {
  display: block;
  width: 124px;
  height: 72px;
  object-fit: cover;
  border: 1px solid #c8d8e4;
  background: #fff;
}

.site-page--cases .case-intro-media .editorial-gallery figcaption {
  display: none;
}

.site-page--cases .case-intro-copy {
  display: flex;
  flex-direction: column;
  justify-content: center;
  max-width: none !important;
  padding: 0;
}

.site-page--cases .case-intro-copy .pim-eyebrow {
  margin-bottom: 14px;
}

.site-page--cases .case-intro-copy .pim-h1 {
  margin-bottom: 18px;
}

.site-page--cases .case-intro-copy .pim-lede {
  margin-bottom: 14px;
  color: #41586b;
}

.site-page--cases .case-intro-copy .pim-hero-support {
  margin: 0;
  color: #6b7e8d;
}

.site-page--cases .case-detail .case-explorer {
  margin-top: 0;
}

@media (max-width: 980px) {
  .site-page--cases .case-intro-grid {
    grid-template-columns: 1fr;
    gap: 28px;
  }

  .site-page--cases .case-intro-media { order: 1; }
  .site-page--cases .case-intro-copy { order: 2; }
}

@media (max-width: 720px) {
  .pim-h1,
  .home-hero .pim-flow-payoff .pim-h1,
  .site-page--features .feature-page-hero .pim-h1,
  .consult-page > .pim-pagehero .pim-h1,
  .site-page--agent .agent-page-hero .pim-h1,
  .site-page--cases .pim-pagehero .pim-h1 {
    font-size: clamp(34px, 10.5vw, 43px) !important;
  }

  .site-page--cases .case-detail > .case-intro-split {
    padding-block: 38px;
  }

  .site-page--cases .case-intro-media .editorial-gallery figure,
  .site-page--cases .case-intro-media .editorial-gallery img {
    width: 104px;
    flex-basis: 104px;
  }

  .site-page--cases .case-intro-media .editorial-gallery img {
    height: 62px;
  }
}


.home-workflow-visual img { width: min(100%, 150px); height: 70px; display: block; object-fit: contain; }

/* v3 header tuning ---------------------------------------------------------
   The nav links are the only header anchors bumped: reference-polish-pass4
   sets 12px on `.pim-header a`, which also catches the "Talk to us" button. */
.main-nav a,
.pim-nav a { font-size: 15px; font-weight: 500; }

/* v3 hero flow: quote the brand mark ---------------------------------------
   reference-visual-pass sets the tile and hub colours at `.home-hero .pim-flow-*`,
   so these match or beat that specificity from a later sheet. */

/* The three inputs become the mark's white squares, glyphs in its navy. */
.home-hero .pim-flow-node--in .pim-flow-node-icon {
  color: #0B2F6B;
  background: #fff;
  border-color: rgba(11, 47, 107, .14);
  box-shadow: 0 0 22px rgba(120, 190, 255, .3);
}

/* The mark's left satellite is a rotated square, so Database takes that shape;
   the glyph counter-rotates to stay upright. Rotation is a transform, so the
   tile's layout box — and the wire that meets it — does not move. */
.home-hero .pim-flow-node--diamond .pim-flow-node-icon { rotate: 45deg; }
.home-hero .pim-flow-node--diamond .pim-flow-node-icon svg { rotate: -45deg; }

/* That rotation puts the lower vertex ~1.6cqw past the tile's box, close enough
   to touch the label under flow.css's 0.7cqw gap. Widened on every node so all
   seven labels stay on one line with each other. */
/* Base is the mark's state, so the gap between tile and caption is zero and
   the value the diagram uses is handed to the keyframe instead.

   The panel goes with it. reference-visual-pass gives the node a
   rgba(4,31,55,.93) background on an 88px min-width — a box wider than its
   55px tile, painted after the hub because the nodes follow it in the markup.
   In the mark that put a dark vertical edge over the circle: the diamond's node
   box ended at -32.3 and the disc starts at -33.9. It was also the grey slab
   that showed behind the white tiles in the diagram. */
.home-hero .pim-flow-node {
  --pim-node-gap: 2.2cqw;
  gap: 0;
  min-width: 0;
  background: transparent;
  box-shadow: none;
}

/* The hub is the mark's centre circle, nothing inside it. */
.home-hero .pim-flow-hub { background: #0A66FF; }

/* v3 cases page ------------------------------------------------------------
   .case-index wraps the whole page, hero included, but pass4 gives it a
   section's padding — so its top pad (clamp 58-92px) landed above the hero as
   dead white space rather than between two sections. The hero keeps its own
   44px, so the heading still clears the header. */
.site-page--cases .case-index { padding-top: 0; }

/* v3 pricing ---------------------------------------------------------------
   The old card ran name, summary, everything included, limits, and only then
   the price and the button — so the two things a visitor is scanning for sat at
   the bottom, at a different height in each column because the lists above them
   are 2, 4 and 7 items long. And the price was set at clamp(34px, 4vw, 52px) in
   display caps, which put "FROM 250 € / MONTH" on two lines at 52px.

   Now: name, summary, price, button, then the detail. The first four are fixed
   height, so the three buttons line up; the lists hang below and are free to
   differ. */
.site-page--pricing .pricing-grid .pricing-card.pim-plan {
  display: flex;
  flex-direction: column;
  padding-top: 34px;
}

/* Two lines reserved: the summaries are one line wide and two lines narrow, and
   without this the price below them steps between columns. */
.site-page--pricing .pim-plan-summary {
  min-height: 2.9em;
  margin-bottom: 4px;
  font-size: 13px;
  line-height: 1.45;
}

/* Price and button share a row: the amount reads on the left, the action sits
   against the right edge where the eye ends up. They wrap to two lines if a
   card ever gets too narrow for both. */
.site-page--pricing .pim-plan-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 18px 0 20px;
  border-top: 1px solid var(--ref-line);
  border-bottom: 1px solid var(--ref-line);
  margin-bottom: 20px;
}

/* Overrides the display-caps price: an amount is a number, not a headline. */
.site-page--pricing .pricing-grid .pim-plan-price {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  font-size: inherit;
  letter-spacing: normal;
  text-transform: none;
}

/* Enterprise spends this line on a blank, so all three price blocks are the
   same three lines tall and the amounts and buttons align without a min-height
   that has to be re-guessed whenever the type changes. */
.site-page--pricing .pim-plan-price-from {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ref-blue-600);
}

.site-page--pricing .pim-plan-price-amount {
  font-family: var(--pim-font-display);
  font-size: 34px;
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -.03em;
  color: var(--ref-ink);
}

.site-page--pricing .pim-plan-price-unit {
  font-size: 12px;
  color: var(--ref-copy);
}

.site-page--pricing .pim-plan-cta.pim-btn {
  flex: 0 0 auto;
  align-self: center;
  justify-content: center;
  width: auto;
  box-shadow: none;
}

/* Takes the slack, which keeps the footnote on the bottom edge. */
.site-page--pricing .pim-plan-detail { flex: 1 1 auto; }
.site-page--pricing .pim-plan-detail .pim-ticks { margin-top: 0; }
.site-page--pricing .pim-plan-note { margin-top: 18px; margin-bottom: 0; }

/* The recommended plan. The featured card already carries the 4px top rule and
   the tinted wash from reference-visual-pass; this is the label that says why. */
.site-page--pricing .pim-plan-badge {
  position: absolute;
  top: 10px;
  right: 16px;
  margin: 0;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ref-blue-600);
}

/* v3 agent console --------------------------------------------------------
   The panel starts empty. site.css already ships that state — an
   .pim-console-panel--empty article shown by `:not(:has(:checked))` — but a
   later rule in the same file swapped it for the first replay, on the grounds
   that an empty console "looks empty". It is meant to: nothing runs until a job
   is pressed. */
.site-page--agent .pim-console:not(:has(.pim-console-radio:checked)) .pim-console-panel--empty {
  display: block;
}

.site-page--agent .pim-console:not(:has(.pim-console-radio:checked)) .pim-console-panel:first-of-type {
  display: none;
}

/* Was a centred section heading above the whole console; it belongs to the
   panel, so it sits at the top of the panel column and is sized as a caption
   rather than as a page heading. */

/* v3 beta ribbons ---------------------------------------------------------
   reference-theme redefines --pim-tone-gold as --ref-blue-600, so everything
   that asked for gold came out blue — including these. One amber pair, used
   for both the rail's beta markers and the word in the pricing footnote, so
   the two read as the same mark: a bright fill that carries dark text, since
   the fill colour itself has nowhere near enough contrast to be text on white.

   Shaped as a flag rather than a 45-degree corner banner: the rail rows are
   54px tall and a corner banner crosses exactly where the cue arrow sits. */
:root {
  --v3-beta-fill: #F2B01E;
  --v3-beta-ink: #43310A;
}

.site-page--agent .pim-console-beta,
.site-page--features .pim-feature-beta,
.site-page--pricing .pim-plan-note-term {
  padding: 1px 6px 1px 9px;
  border: 0;
  border-radius: 2px;
  /* The notch on the left edge is the ribbon's tail. */
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, 4px 50%);
  font-size: 8px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--v3-beta-ink);
  background: var(--v3-beta-fill);
}

.site-page--pricing .pim-plan-note-term {
  display: inline-block;
  margin: 0 2px;
  vertical-align: 1px;
}

/* The empty panel's second line is the actionable one — it says what to do —
   but site.css sets it smaller and fainter than the line above it. Turned
   round: it carries the panel's teal accent, more weight, and a slow breath so
   the eye finds it in an otherwise blank panel. */
.site-page--agent .pim-agentempty-hint {
  margin-top: 0.7rem;
  font-size: 0.95rem;
  font-weight: 650;
  color: var(--app-accent-11);
  animation: v3-hint-breathe 2.4s ease-in-out infinite;
}

@keyframes v3-hint-breathe {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

@media (prefers-reduced-motion: reduce) {
  .site-page--agent .pim-agentempty-hint { animation: none; }
}

/* v3 landing intro --------------------------------------------------------
   site.css:3474-3482 switches most of the hero choreography off for .home-hero:
   `animation: none` on the stage, the payoff, the lines, the nodes, the hub and
   the chips, with the lines additionally pinned to stroke-dashoffset 0 — so the
   wires were simply present from the first frame. This puts back the three that
   build the diagram.

   The shorthand `animation: none` resets every longhand, so each one has to
   restore its timing function and fill mode as well as its name: the whole file
   depends on fill-mode both, which is what keeps the hidden start state in the
   keyframes and off the base rule.

   Both guards are load-bearing. `.pim-flow--skipped .pim-flow-line` and the
   reduced-motion block are single-class selectors, so these rules would
   outrank them and the skip would leave undrawn wires and invisible nodes on
   screen — measured, before the guards went in. `:not()` keeps the skip
   working and the media query keeps reduced motion working.

   Deliberately still off:
   - .pim-flow-payoff — its keyframe starts at opacity 0 and scale 0.18 to grow
     out of the hub, but v3 puts the headline in a static left-hand grid column.
     Re-enabling it would blank the hero copy until the animation ran.
   - .pim-flow-stage — its base state is the handed-over one, blur(2px)
     brightness(0.42), which v3 overrides with filter: none because the diagram
     is the hero visual and stays. Re-enabling it would end on a blurred diagram.
   Nothing else is left off. */
@media (prefers-reduced-motion: no-preference) {
  .home-hero:not(.pim-flow--skipped) .pim-flow-line {
    animation-name: pim-flow-draw;
    animation-timing-function: ease-in-out;
    animation-fill-mode: both;
  }

  .home-hero:not(.pim-flow--skipped) .pim-flow-node {
    animation-name: pim-flow-node-in, pim-flow-logo-place;
    animation-timing-function: cubic-bezier(0.2, 0.8, 0.3, 1), cubic-bezier(0.5, 0, 0.2, 1);
    animation-fill-mode: both, both;
  }

  .home-hero:not(.pim-flow--skipped) .pim-flow-hub {
    animation-name: pim-flow-hub-in, pim-flow-absorb, pim-flow-logo-hub;
    animation-timing-function: cubic-bezier(0.2, 0.8, 0.3, 1), ease-out, cubic-bezier(0.5, 0, 0.2, 1);
    animation-fill-mode: both, none, both;
  }

  /* Each roster chip arrives as its own badge is consumed. The original
     choreography already pairs them: a badge is swallowed at 78% of its 1.8s,
     so badge 1 at 2.20s vanishes at 3.60s and chip 1 is timed to 3.60s, and the
     same holds for the 3.60/5.01 waves. No retiming, and the roster finishes
     filling at 7.22s, just as the exports settle. */
  .home-hero:not(.pim-flow--skipped) .pim-flow-chip {
    animation-name: pim-flow-settle;
    animation-timing-function: cubic-bezier(0.2, 0.9, 0.3, 1.4);
    animation-fill-mode: both;
  }

  /* The falling badges, on their original 2.20-5.37s waves: three at a time
     dropping in above the hub and travelling into it, which is what fills the
     stretch between the names appearing and the bars merging. They are hidden
     with `display`, not `animation`, so the same two guards are what keep the
     skip class and reduced motion working — both of those also use display. */
  .home-hero:not(.pim-flow--skipped) .pim-flow-badge {
    display: block;
  }
}

/* v3 flow pill tones ------------------------------------------------------
   reference-theme flattens all nine --pim-tone-* tokens to --ref-blue-600, so
   every badge, chip, card glyph and case accent on the site came out the same
   blue. Those tokens stay flattened — this only re-separates the nine the hero
   flow uses, by overriding --pim-flow-tone rather than the shared tokens, so
   nothing outside the diagram changes.

   Kept bright enough to glow on the navy stage: the pill derives its text, its
   16% background, its 48% border and its text-shadow from this one value, so a
   dark hue would take the whole pill down with it. Mid-blue is deliberately not
   in the set — that is the wires' colour, and the badges need to read as
   something else arriving. */
.home-hero .pim-flow-pill--lilac { --pim-flow-tone: #B79CFF; }
.home-hero .pim-flow-pill--plum  { --pim-flow-tone: #E58FD8; }
.home-hero .pim-flow-pill--mint  { --pim-flow-tone: #6EE7B7; }
.home-hero .pim-flow-pill--sky   { --pim-flow-tone: #7CC4FF; }
.home-hero .pim-flow-pill--peach { --pim-flow-tone: #FFB37A; }
.home-hero .pim-flow-pill--gold  { --pim-flow-tone: #F2C64B; }
.home-hero .pim-flow-pill--aqua  { --pim-flow-tone: #5FE3E8; }
.home-hero .pim-flow-pill--sage  { --pim-flow-tone: #A8DE7A; }
.home-hero .pim-flow-pill--coral { --pim-flow-tone: #FF7A5C; }
.home-hero .pim-flow-pill--rose  { --pim-flow-tone: #FF9BB5; }

/* v3 roster: two rows ------------------------------------------------------
   Three rows of three reached up to y 72.9%, which is where the mark's lower
   square has to sit. Flowed instead of gridded: the nine labels are 8-22cqw
   wide, so fixed columns either wrapped the long ones onto a third line or
   needed a roster wide enough to run into the export column at 79%. Wrapping a
   centred flex row keeps both rows centred on each other and lets each chip
   take its own width. The type comes down a little to make two rows fit inside
   the 56cqw. */
.home-hero .pim-flow-roster {
  grid-template-columns: repeat(5, 1fr);
  align-content: center;
}

/* Five columns and ten capabilities: two full rows, and no dependence on how
   the labels happen to pack. Wrapping a flex row gave 6/3 at 1440px, 5/4 at
   1250px and three rows below that. */

/* The floor is the thing that has to come down. flow.css sets
   clamp(8px, 1.02cqw, 12px), and at 1100px the stage's cqw is 5.1px — so the
   text is pinned at the 8px floor while the roster keeps shrinking, and the
   chips get relatively wider until nine of them need three rows. A 6px floor
   holds the proportion far enough down the range. */
.home-hero .pim-flow-chip {
  padding: 0.42cqw 0.62cqw;
  font-size: clamp(6px, 0.86cqw, 10px);
}

/* v3 landing: the diagram is the hero ------------------------------------
   The intro now carries the whole message — wordmark, motto, tagline and the
   same two buttons the left column had — so that column was saying everything
   twice. It is removed from the layout rather than deleted: the h1 stays in the
   document, visually hidden, because the page needs a heading and the wordmark
   inside the diagram is a div in a decorative stage. */
.home-hero .pim-flow-payoff {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.home-hero .pim-flow-payoff .pim-eyebrow,
.home-hero .pim-flow-payoff .pim-lede,
.home-hero .pim-flow-payoff .pim-actions {
  display: none;
}

/* One column, and the stage takes its natural 1160px maximum — which is also
   the width its viewBox was drawn for, so the diagram stops being squeezed into
   the 760px the two-column layout gave it. */
.home-hero.pim-flow {
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
}

.home-hero .pim-flow-stage {
  grid-column: 1;
  max-width: 1160px;
  /* No panel. reference-visual-pass draws the stage as a bordered, tinted card
     with its own 28px grid, over a section that already has a 44px grid of its
     own — two grids at different pitches, plus a rounded border round a diagram
     that is now the whole hero. The animation runs on the page instead.

     The 22px padding stays: it is the container-query box that every cqw in the
     diagram is measured against, so dropping it would resize the whole mark. It
     is just invisible breathing room now. */
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}

/* Closer to the top: the section reserved 68px above a stage whose own top
   eighth is empty by construction, so the diagram sat low with a lot of nothing
   over it. */
.home-hero.pim-flow {
  min-height: 0;
  padding-top: 8px;
  padding-bottom: 28px;
}

/* The header wordmark matches the one the intro ends on. It has to be scoped to
   .pim-brand: reference-theme sets .brand-name to --pim-font-sans, but site.css
   also has `.pim-brand span { font-family: var(--pim-font-brand) }`, and that
   descendant selector outranks both — which is why the header was Orbitron
   rather than the IBM Plex the theme asked for. The hyphen is left alone: at
   17px the lopsidedness Manrope gives it is under 3px, and correcting it would
   mean the same three spans in all eleven page headers. */
.pim-brand .brand-name { font-family: var(--pim-font-display); }

/* v3 wordmark hyphen ------------------------------------------------------
   Lives here rather than in flow.css because flow.css is only linked on the
   landing page, and the header and footer wordmarks are on all eleven. */
/* The hyphen is drawn, not typeset. `background-clip: text` on the glyph did
   carry the gradient, but a hyphen is 0.095em tall — about 4px at 49px — and
   only its middle rows land on whole pixels, so antialiasing muted it to
   rgb(40,180,243) where the ramp should have been brighter. (Nothing on the
   page dims colour: the hub's #0A66FF renders as exactly rgb(10,102,255) in the
   same frame.)

   So the glyph stays for the accessible name with a transparent fill, keeping
   its advance and the layout, and a pseudo-element paints the bar over it:
   crisp, and roundable the way the mark's own square is.

   The box is the hyphen's measured ink, taken off a 200px render with
   line-height 1 — offset 0.060em / 0.515em, 0.300em x 0.095em — which is why
   the span has to be inline-block at line-height 1 for those offsets to mean
   what they meant when measured. Radius is the square's own 4.7/22 ratio
   applied to the bar's height. */
.pim-flow-appname-dash,
.pim-brand-dash {
  position: relative;
  display: inline-block;
  line-height: 1;
  color: transparent;
  text-shadow: none;
}

.pim-flow-appname-dash::before,
.pim-brand-dash::before {
  content: "";
  position: absolute;
  /* Two levers set the gaps round the bar independently now that it is a box:
     the span's margin-left moves the bar *and everything after it*, so it sets
     the gap on the left; the bar's own offset inside the span moves only the
     bar, so it trades one gap against the other.

     0.088em is for the 49px wordmark: 10px on the M side, 2px on the T side.
     The whole space between the two letters is 12px, so the reachable steps are
     just 6/6, 7/5, 8/4, 9/3, 10/2 and 11/1 — and equal ink is not the target.
     At the bar's own height the nearest ink to its right is the T's *stem*, in
     the middle of the letter, not the crossbar up at cap height; so the visual
     gap on the right is about half a T wider than the measured one, and the bar
     has to sit well right of "balanced" to look centred. Chosen by eye off a
     rendered A-F strip after three measured attempts were all rejected.

     The header overrides this below: 17px has about 4px of slack in total, so
     one em value cannot serve both sizes. */
  left: 0.088em;
  top: 0.515em;
  width: 0.300em;
  height: 0.095em;
  border-radius: 0.02em;
  background-image: linear-gradient(90deg, #2F7BFF, #22E3E9);
}

/* The header, matching the big wordmark's proportion as closely as 17px allows.
   With about 4px of slack the bar alone saturates at 2/1 — it runs out of span
   to move into — so the extra left-hand room comes from a margin on the span,
   which moves the bar and everything after it. Together: 3px on the M side and
   1px on the T side, the nearest reachable to the 5:1 the big one now has. */
.pim-brand-dash { margin-left: 0.05em; }
.pim-brand-dash::before { left: 0.120em; }

/* The nav and footer wordmark's I gets the same air the big one has. 0.06em is
   one pixel each side at the header's 17px — the finale's 0.07em is a little
   over three at 49px, which is why the big one already looked open and this one
   did not. */
.pim-brand-i { margin-inline: 0.06em; }

/* v3 small screens: the same animation, smaller ---------------------------
   flow.css takes the stage apart below 820px — aspect-ratio auto, the stage a
   flex column, the hub and nodes unpositioned, the wires hidden — and
   reference-visual-pass hides the stage outright below 640px. That was right
   when a copy column carried small screens; now that the diagram *is* the hero,
   hiding it leaves an empty band.

   Everything inside the diagram is already sized in cqw against the stage, so
   it scales on its own once the stage keeps its aspect-ratio. These rules put
   back what the stacked layout undoes, for the landing hero only — the app's
   own /flow page and any other stage still get the stacked treatment. */
.home-hero .pim-flow-stage {
  display: block;
  aspect-ratio: 1160 / 640;
}

@media (max-width: 820px) {
  .home-hero .pim-flow-wires { display: block; }

  .home-hero .pim-flow-hub {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: var(--pim-logo-diameter, 9.354cqw);
    margin: 0;
  }

  .home-hero .pim-flow-node {
    position: absolute;
    transform: translate(-50%, -50%);
    flex-direction: column;
    width: auto;
  }

  .home-hero .pim-flow-roster {
    position: absolute;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 60cqw !important;
    grid-template-columns: repeat(5, 1fr) !important;
  }

  .home-hero .pim-flow-node-icon {
    width: 7.6cqw;
    height: 7.6cqw;
    border-radius: 1.6cqw;
  }

  /* The px floors in these clamps are what actually break at phone widths: at
     390px the stage's cqw is 3.5px, so a 9px floor renders the labels at nearly
     three times their intended size and they overflow their own tiles. Floors
     drop so the type keeps scaling with the drawing. Below roughly 600px the
     labels stop being readable and the diagram is decorative — a legible
     small-screen version needs a different composition, not a smaller one. */
  .home-hero .pim-flow-node-label { font-size: clamp(5px, 1.18cqw, 13.5px); }
  .home-hero .pim-flow-chip { font-size: clamp(4px, 0.86cqw, 10px); }
  .home-hero .pim-flow-pill { font-size: clamp(4px, 1.02cqw, 12px); }
  .home-hero .pim-flow-appname { font-size: clamp(13px, 5.4cqw, 68px); }
  .home-hero .pim-flow-motto { font-size: clamp(9px, 3.6cqw, 44px); }
  .home-hero .pim-flow-outro-copy p { font-size: clamp(6px, 1.6cqw, 18px); }
  .home-hero .pim-flow-outro-actions .pim-btn { font-size: clamp(5px, 1.25cqw, 14px); }
}

/* v3 header: nav centred on the page ---------------------------------------
   With the Talk-to-us button gone the header has two visible children — the
   wordmark and the nav — so site.css's `auto 1fr auto` left the nav centred in
   whatever the wordmark did not take, which is right of the page's centre.
   `1fr auto 1fr` puts it in the middle column instead, so it is centred on the
   page and stays there whatever the wordmark's width. Above 900px only: below
   that site.css switches to `1fr auto` for the burger. */
@media (min-width: 901px) {
  .nav-shell,
  .pim-header-inner {
    grid-template-columns: 1fr auto 1fr;
  }

  .pim-header-inner .pim-brand {
    justify-self: start;
  }
}

/* v3 three-steps strip ----------------------------------------------------
   Heading in black, and the section loses the padding it was carrying at both
   ends: pass4 gives .pim-section clamp(58px, 6.5vw, 92px) top and bottom, and
   site.css adds another 68px/34px inside the intro on top of that. */
.workflow-section.pim-section {
  padding-top: 18px;
  /* More room under the cards than over them: the next section is dark, and at
     18px the row sat right on that edge. */
  padding-bottom: 44px;
}

.workflow-section .section-intro {
  padding: 14px 0 10px;
  margin-bottom: 10px;
}

.workflow-section .section-intro .pim-h2 {
  color: #000;
}

/* The step numbers are filled now, each in its own colour with a black stroke,
   rather than the outlined pale blue they were. -webkit-text-fill-color is what
   actually paints the glyph when a text-stroke is in play, so `color` alone
   would not show; site.css and reference-visual-pass both set it to transparent
   and site.css sets the stroke colour to --technical-blue, so both have to be
   answered here. */
/* Only 01 is stroked: white on white, the stroke is the whole glyph. 02 and 03
   read on their own, and a black outline on them just muddied the colour. */
.home-workflow-card--ingest .home-workflow-step {
  color: #fff;
  -webkit-text-fill-color: #fff;
  -webkit-text-stroke: 1px #000;
  -webkit-text-stroke-color: #000;
}

/* the hub's blue */
.home-workflow-card--enrich .home-workflow-step {
  color: #0A66FF;
  -webkit-text-fill-color: #0A66FF;
  /* reference-visual-pass strokes every step number 1px #9dcdf0 — the outlined
     treatment these had before they were filled. Removing the black stroke I
     had added left that pale blue one behind, still reading as an outline. */
  -webkit-text-stroke: 0;
}

/* the lightest stop of the mark's gradient square */
.home-workflow-card--publish .home-workflow-step {
  color: #22E3E9;
  -webkit-text-fill-color: #22E3E9;
  /* reference-visual-pass strokes every step number 1px #9dcdf0 — the outlined
     treatment these had before they were filled. Removing the black stroke I
     had added left that pale blue one behind, still reading as an outline. */
  -webkit-text-stroke: 0;
}

/* The arrow carries a label now, so it stops being a 36x30 icon box. */
.home-workflow-card .home-workflow-link {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  width: auto;
  height: auto;
  margin-top: auto;
  padding-top: 12px;
  font-family: var(--pim-font-sans);
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}

/* v3 two halves -----------------------------------------------------------
   The frame matches its asset again. orvex-dark.webp is 1600x900, but
   reference-visual-pass spans the frame across both grid rows, so on a wide
   screen it grew to 588x709 — portrait — and `cover` answered by cropping away
   over half the width and zooming into the middle. Hence the photo reading as
   off-centre: it was a narrow vertical slice of a landscape shot. A 16/9 box
   centred in its column shows the whole frame as composed. */
.product-proof .pim-shell::before {
  aspect-ratio: 16 / 9;
  min-height: 0;
  height: auto;
  align-self: center;
  /* The bottom vignette moves here from the ::after, which is absolutely
     positioned at a fixed `top: 42px; height: 356px` — geometry that matched the
     old full-height frame and now sits about 100px above this one, casting its
     shadow on nothing. On the frame it tracks the frame. */
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.025),
    inset 0 -80px 100px rgba(2, 18, 33, 0.12);
}

.product-proof .pim-shell::after {
  display: none;
}

/* The intro was inheriting site.css's `1fr .78fr` two-column grid, which put
   the eyebrow in one column and the heading in the other — so the block read as
   scattered rather than as one heading. One centred column instead, and bigger:
   pass4 pins .pim-h2 with !important, so this has to answer in kind. */
.product-proof .section-intro {
  display: block;
  text-align: center;
}

.product-proof .section-intro .pim-h2 {
  max-width: 22ch;
  margin-inline: auto;
}

.product-proof .section-intro > p {
  max-width: 56ch;
  margin-inline: auto;
}

/* v3 section backgrounds ---------------------------------------------------
   Two sections were carrying their own one-off fills instead of the two
   backgrounds the page already establishes, so the page read as four
   different surfaces. Both values below are copied from the computed style of
   the section they are matching, not re-derived.

   Two halves took a flat 90deg blue ramp; it now uses the landing hero's
   surface — navy base, 42px grid, the off-centre radial glow, and the 135deg
   ramp underneath. */
.product-proof.product-section {
  background-color: #03182C;
  background-image:
    linear-gradient(rgba(40, 145, 222, 0.075) 1px, transparent 1px),
    linear-gradient(90deg, rgba(40, 145, 222, 0.075) 1px, transparent 1px),
    radial-gradient(circle at 78% 58%, rgba(20, 130, 225, 0.18), transparent 38%),
    linear-gradient(135deg, #03182C, #05213A 67%, #07345B);
  background-size: 42px 42px, 42px 42px, auto, auto;
}

/* 3 Steps was flat white; it now matches "Bring your own file" — the pale
   blue panel with its own 44px grid. */
.workflow-section.pim-section {
  background-color: #EEF5FB;
  background-image:
    linear-gradient(rgba(71, 139, 195, 0.043) 1px, transparent 1px),
    linear-gradient(90deg, rgba(71, 139, 195, 0.043) 1px, transparent 1px);
  background-size: 44px 44px, 44px 44px;
}

/* v3 3 Steps: cards, not a strip -------------------------------------------
   reference-visual-pass builds the row as one seamless strip: gap 0, a rule
   along the top and bottom of the container, and a right border on each card
   as the divider. Adding a gap to that leaves the dividers floating in it, so
   the strip furniture comes off and each card gets its own outline. Now that
   the section is the pale panel, the white cards read as cards. */
.workflow-section .home-workflow-cards {
  gap: 18px;
  border-top: 0;
  border-bottom: 0;
}

.workflow-section .home-workflow-card {
  border: 1px solid #D3E0E9;
  border-radius: 6px;
}

/* v3 features: land the anchor level with the rail -------------------------
   site.css offsets these by 208px, which fits the horizontal ribbon the class
   name still remembers (`feature-process-ribbon`). It is a left rail now —
   sticky in its own column, so it never covers the content vertically — and
   the only sticky chrome above the text is the 61-65px header. 208px stopped
   the scroll 147px high, which is why the panel above stayed on screen.

   The offset is the rail's own sticky top, not a clearance guess: the panel
   lands level with the top of the rail beside it. Both read the one custom
   property so they cannot drift apart — an 80px offset against the rail's
   72px was what left the panel sitting 8px low. */
:root {
  --v3-feature-anchor-top: 72px;
}

.site-page--features .feature-rail {
  top: var(--v3-feature-anchor-top);
}

.pim-feature {
  scroll-margin-top: var(--v3-feature-anchor-top);
}

/* v3 services hero: the four case plates as a 2x2 -------------------------
   Was one plate (voltra) cropped to a tall box. All four plates are 1600x900,
   so a 16/9 frame makes each quadrant exactly 16/9 too and `50% 50%` lands
   pixel-exact with no distortion — no cropping, no stretching. 1px comes off
   each quadrant so the panel colour shows through as a hairline gutter.
   Fixing the aspect means the frame can no longer stretch to the hero's
   height, so it centres instead. */
.consult-page > .pim-pagehero::after {
  top: 50%;
  bottom: auto;
  height: auto;
  aspect-ratio: 16 / 9;
  translate: 0 -50%;
  background-color: #CADBE6;
  background-image:
    url("../img/editorial/orvex-plate.webp"),
    url("../img/editorial/auria-plate.webp"),
    url("../img/editorial/voltra-plate.webp"),
    url("../img/editorial/cylinder-plate.webp");
  background-position: left top, right top, left bottom, right bottom;
  background-size: calc(50% - 1px) calc(50% - 1px);
  background-repeat: no-repeat;
}

/* v3 cases "Your vertical may not be one of these four" --------------------
   Was site.css's two-column .section-intro: the heading in a 289px column,
   the lede in a 415px one beside it, the pair left-aligned and pinned at a
   fixed 760px that did not track the screen. Now one centred block sitting
   above the cards, held a little narrower than the three-card row and
   reflowing with it rather than at a fixed width. */
.case-proof .case-proof-intro .section-intro {
  display: block;
  max-width: 88%;
  margin-inline: auto;
  text-align: center;
}

/* site.css sets `text-align: left` on this heading specifically
   (.case-proof-intro .pim-h2, from when it was the left column of the old
   two-column intro). Centring the block moved its box but not its text. */
.case-proof .case-proof-intro .pim-h2 {
  text-align: center;
}

/* site.css caps the lede at 908px, which left the paragraph reading well
   inside the block and the block reading much narrower than the card row. It
   fills the block now, so the whole intro is the 88% it is set to. */
.case-proof .case-proof-intro .pim-lede {
  max-width: none;
}

/* v3 pricing rework -------------------------------------------------------
   Three separate cards, and one palette.

   The row was a single bordered strip with `gap: 0` and a right border per
   card as the divider — the same construction as the 3 Steps row. The narrow
   breakpoint already broke it into separate bordered cards at `gap: 12px`;
   this is that treatment at every width, so the container furniture comes off
   and each card carries its own outline. */
/* White cards on a white section show only their outlines, which reads as the
   strip they used to be. The section takes the same pale panel the rest of
   the page uses — the "Bring your own file" surface, also now under 3 Steps —
   so the cards read as cards. */
/* Specificity: reference-theme paints this section with
   `.pricing-page #engagements`, an id selector, so a class selector cannot
   reach it. Qualifying the id gets above it. */
.site-page--pricing #engagements.pricing-plans {
  background-color: #EEF5FB;
  background-image:
    linear-gradient(rgba(71, 139, 195, 0.043) 1px, transparent 1px),
    linear-gradient(90deg, rgba(71, 139, 195, 0.043) 1px, transparent 1px);
  background-size: 44px 44px, 44px 44px;
}

.site-page--pricing .pricing-grid {
  gap: 18px;
  border: 0;
  border-radius: 0;
  background: transparent;
  overflow: visible;
}

/* pass4 builds the strip with `border: 0 !important` plus a
   `border-right: 1px !important` divider, and drops the divider on the last
   card. Every edge of it is !important, so the outline has to answer in kind
   or the cards come back open on three sides. (pass4 itself restores a full
   border below 980px, where the strip already broke into cards.) */
.site-page--pricing .pricing-grid .pricing-card.pim-plan,
.site-page--pricing .pricing-grid .pricing-card.pim-plan--featured {
  border: 1px solid #D3E0E9 !important;
  background: #fff;
}

/* The recommended card keeps its wash, and its top rule becomes the mark's
   gradient — the same blue-to-cyan ramp as the export square — instead of a
   flat blue bar. */
.site-page--pricing .pricing-grid .pricing-card.pim-plan--featured {
  background: linear-gradient(180deg, #EDF8FF 0, #fff 46%);
  border-color: #A6D2EF !important;
}

.site-page--pricing .pricing-grid .pricing-card.pim-plan--featured::before {
  background-image: linear-gradient(90deg, #2F7BFF, #22E3E9);
  /* Sits on the card's own top border rather than above it. */
  top: -1px;
  left: -1px;
  right: -1px;
  border-radius: 4px 4px 0 0;
}

/* The plan name was a `.pim-pill`: a tinted capsule with a border, a 20px
   outer glow, a 1px inset highlight and a text-shadow halo — which is what
   made three plan names read as three shadowed buttons. reference-theme had
   already recoloured it and left every shadow in place. It is a label now. */
.site-page--pricing .pricing-grid .pim-pill {
  margin: 0 0 6px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  text-shadow: none;
  color: #0A66FF;
  font-size: 12px;
  letter-spacing: .14em;
}

/* One blue for the whole section, the app's #0A66FF, instead of the per-card
   sky/mint/gold tones — reference-theme had already remapped gold to blue, so
   the row was two blues and a mint. */
.site-page--pricing .pricing-grid .pim-icon--tick {
  color: #0A66FF;
}

.site-page--pricing .pricing-grid .pim-plan-price-amount {
  color: #03182C;
}

.site-page--pricing .pricing-grid .pim-plan-price-from,
.site-page--pricing .pricing-grid .pim-plan-limits-label {
  color: #0A66FF;
}

/* Buttons: the solid one in the brand blue, the outlined ones bordered in it
   so all three read as the same action at two weights. No shadow on either. */
.site-page--pricing .pim-plan-cta.pim-btn--primary {
  border-color: #0A66FF;
  background: #0A66FF;
  color: #fff;
}

.site-page--pricing .pim-plan-cta.pim-btn--ghost {
  border-color: #9FC4F5;
  background: #fff;
  color: #0A66FF;
}

/* The Beta mark inside the Enterprise tick list is the pricing footnote's
   ribbon, reused rather than restyled so the two are the same mark. */
.site-page--pricing .pim-ticks .pim-plan-note-term {
  margin-left: 4px;
}

/* v3 features: the two columns start level ---------------------------------
   The rail and the panel column are siblings in the shell, both starting at
   the same y — but site.css gives .feature-sections `padding: 52px 0 82px`,
   so the first panel began 52px below the rail beside it. On load the two
   read as misaligned; every later panel is fine because it is scrolled to.
   Zeroed here: the panels carry their own 38px of internal padding, so the
   card's top edge is what lines up with the rail's.

   And the whole block comes up: pass4 gives .pim-section
   clamp(58px, 6.5vw, 92px) top and bottom, which at desktop put 92px of air
   above both columns. A third of that is enough to separate them from the
   hero. */
.site-page--features .feature-sections {
  padding-top: 0;
}

.site-page--features .feature-explorer {
  padding-top: clamp(24px, 2.8vw, 40px);
}

/* v3 features hero: the schematic, no card --------------------------------
   The visual beside the H1 was a product-editor screenshot filled with
   `cover`, inside a bordered card with a shadow. Its box is 423px tall at
   every width but 490-700px wide, so its aspect swings from 1.16 to 1.66 —
   `cover` on a labelled drawing would crop a different slice of the labels at
   every screen size.

   The drawing sits on the page instead: no border, no card background, no
   shadow, no radius. That only works because the asset's own paper was keyed
   out to alpha — an opaque near-white rectangle would have gone on reading as
   a white card with the card's chrome removed. The box carries the trimmed
   asset's 1.545 aspect so `contain` fits it exactly, and `contain` rather than
   `cover` so a later change to either number degrades into space around the
   drawing instead of a crop through it. */
.site-page--features .feature-page-hero::after {
  top: 50%;
  bottom: auto;
  height: auto;
  width: min(46vw, 700px);
  aspect-ratio: 1448 / 937;
  translate: 0 -50%;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background-color: transparent;
  background-image: url("../img/editorial/schematic-lighting.webp");
  background-position: center;
  background-size: contain;
  background-repeat: no-repeat;
}

/* v3 footer: the trust link carries a shield ------------------------------- */
.pim-footer-legal-links a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.pim-footer-legal-links a .pim-icon--shield {
  width: 14px;
  height: 14px;
  flex: none;
}

/* v3 features: legibility and a tighter panel head -------------------------
   The rail links and the cards' bullet rows were both set at 12px — the
   smallest type on the page, carrying the panel's actual claims. 14px each.

   And the head sat 58px down the panel: 38px of panel padding plus 18px of
   its own. The glyph and the heading come up to 26px, which is enough to
   separate them from the panel's top edge without the gap reading as an
   empty band above every card. */
.site-page--features .feature-rail a,
.site-page--features .feature-rail button {
  font-size: 14px;
}

.site-page--features .feature-panel .pim-points-short li,
.site-page--features .feature-panel .pim-points-short span {
  font-size: 14px;
  line-height: 1.45;
}

.site-page--features .feature-panel.pim-feature {
  padding-top: 18px;
}

.site-page--features .feature-panel .pim-feature-head {
  padding-top: 8px;
  padding-bottom: 12px;
}

/* The four-verticals index carried a section's full 92px above its eyebrow,
   directly under a hero that already ends in 34px of its own padding. */
.site-page--cases .case-index-section.pim-section {
  padding-top: 34px;
}

/* v3 trust: the policy-template checklist ---------------------------------
   Eleven policy sections, each a bullet that opens to what belongs in it.
   `<details>`/`<summary>` and nothing else, for the same reasons the
   `.pim-tech` drawer gives: no JavaScript ships on this site, the CSP forbids
   an inline one, and the element is keyboard-operable and still findable by
   in-page search while closed.

   Deliberately lighter than `.pim-tech`: one bordered list with hairline
   dividers rather than eleven stacked panels, and the label in sentence case
   at reading size rather than an uppercase control bar. Eleven of those bars
   would read as eleven sections, not as one checklist. */
/* `.security-page` is a two-column grid for the hero and the editorial image;
   full-bleed sections have to opt in, the way reference-visual-pass does for
   the three that came before this one. Without it the section lays out in
   the hero's 608px column. */
.security-page > .policy-template { grid-column: 1 / -1; }

.pim-checklist {
  margin: 34px 0 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--ice);
}

.pim-checklist-row + .pim-checklist-row { border-top: 1px solid var(--line); }

.pim-checklist-summary {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 13px 18px;
  cursor: pointer;
  color: var(--ink);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.4;
  /* Both are needed: the standard property and the WebKit pseudo-element are
     the two ways a browser draws the default triangle. */
  list-style: none;
}

.pim-checklist-summary::-webkit-details-marker { display: none; }

/* The bullet. A 7px square in the brand blue, so the row reads as a list item
   before anyone discovers it is also a control. It turns to a diamond when the
   row is open, which is the one cue that survives at 320px where the chevron
   is the first thing to get crowded out. */
.pim-checklist-label { flex: 1; }

.pim-checklist-label::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 12px;
  vertical-align: 0.12em;
  background: var(--blue);
  transition: rotate 0.18s ease;
}

.pim-checklist-item[open] .pim-checklist-label::before { rotate: 45deg; }

.pim-checklist-summary:hover { background: var(--ref-blue-100); }

.pim-checklist-summary:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: -2px;
}

.pim-checklist-marker {
  display: inline-grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  flex: none;
  border: 1px solid var(--line);
  border-radius: 50%;
  color: var(--blue);
  background: var(--white);
  rotate: 90deg;
  transition: rotate 0.18s ease;
}

.pim-checklist-item[open] .pim-checklist-marker { rotate: 270deg; }

.pim-checklist-body {
  padding: 0 18px 16px 49px;
  color: var(--muted);
  font-size: 15px;
  line-height: 1.6;
}

.pim-checklist-body p {
  margin: 0;
  max-width: 68ch;
}

@media (max-width: 560px) {
  .pim-checklist-summary { padding: 12px 14px; }
  .pim-checklist-marker { display: none; }
  .pim-checklist-body { padding: 0 14px 14px 33px; }
}

@media (prefers-reduced-motion: reduce) {
  .pim-checklist-marker,
  .pim-checklist-label::before { transition: none; }
}


/* ==========================================================================
   v3 TYPE PASS
   One scale, applied over the seven-stylesheet stack. Most of these carry
   !important because site.css and reference-polish-pass4 already do on the
   same properties; where they do not, the plain declaration wins on being
   last. Sizes stay inside their existing clamp() so the page still responds —
   the numbers below are the desktop values the scale asks for.
   ========================================================================== */

/* --- Headings -------------------------------------------------------------
   h1 was already 50px; what changes is the weight, from 800 to 500, and the
   tracking. At 50px and 800 the display face was doing the work of a poster;
   500 with -0.015em gives page titles a little more breathing room. */
.pim-h1,
h1.pim-h1 {
  font-weight: 500 !important;
  letter-spacing: -0.015em !important;
}

/* h2 to 40px everywhere it is a section heading. Three places had their own
   size: the Two halves heading at 52, the feature panels at 34, and the
   3 Steps cards at 23. The first two join the scale; the cards are card
   titles rather than section headings, so they take the h3 size instead —
   40px inside a third-column card would not fit. */
.pim-h2,
h2.pim-h2 {
  font-weight: 600 !important;
  letter-spacing: -0.015em !important;
}

.site-page--features .feature-panel .pim-h2,
.product-proof .section-intro .pim-h2 {
  font-size: clamp(28px, 3vw, 40px) !important;
}

.home-workflow-card .pim-h2 {
  font-size: 24px !important;
}

/* h3 from 22 to 24, and off 750. */
.pim-h3,
h3.pim-h3 {
  font-size: clamp(20px, 1.9vw, 24px) !important;
  font-weight: 600 !important;
}

/* --- Navigation and buttons ---------------------------------------------- */
.pim-btn,
.pim-btn--lg,
.pim-plan-cta.pim-btn,
.mobile-nav-cta {
  font-size: 15px !important;
  font-weight: 600 !important;
}

/* --- Redirection links ---------------------------------------------------
   The arrow links that send the reader somewhere else. 15px, and the gap
   above them opens to 16px so they read as a step away from the copy rather
   than the last line of it. */
.pim-link,
.pim-study-link,
.home-workflow-link,
.pim-card .pim-link {
  font-size: 15px !important;
  font-weight: 600;
}

.home-workflow-link,
.pim-card .pim-link,
.pim-study-link {
  padding-top: 16px;
}

/* --- Supporting text to 14px ---------------------------------------------
   Captions, notes, footnotes and the pricing detail were sitting between
   11.5 and 13.8. Nothing that is prose now renders under 14px. */
figcaption,
small,
.pim-note,
.pim-plan-note,
.pim-plan-summary,
.pim-plan-limits-label,
.pim-plan-limits li,
.pim-plan-price-unit,
.pim-graph-verb,
.pim-graph-target,
.pim-graph-kind,
.pim-graph-note,
.pim-optrec-relation,
.pim-optrec-dim,
.pim-tech-body li,
code,
code.pim-rule-expr {
  font-size: 14px !important;
}

/* The plan name and the footer column headings were 12px labels. */
.pricing-grid .pim-pill,
.pim-footer-heading,
.footer-heading {
  font-size: 14px !important;
}

/* --- Weight ceiling ------------------------------------------------------
   Nothing over 600 except the wordmark, which keeps its 800 in the header,
   the footer and the animation's finale. */
.pim-case-step,
.pim-plan-price-amount,
.pim-footer-heading,
.footer-heading,
.pim-eyebrow,
.eyebrow,
.pim-plan-badge,
.pim-plan-note-term,
.pim-console-beta,
.pim-feature-beta,
.pim-rule-kw,
.pim-tech-summary,
.home-workflow-step,
.home-workflow-link span,
.pim-checklist-label,
dt,
.pim-deflist dt {
  font-weight: 600 !important;
}

.pim-brand .brand-name,
.pim-brand .brand-name span,
.pim-flow-appname {
  font-weight: 800 !important;
}

/* --- Agent console -------------------------------------------------------
   The console's own running commentary — status lines, tool calls, gate
   options, transcript meta. 13px is deliberate here: it is a dense operator
   log, and the ask names it as the exception to the 14px floor. */
.site-page--agent .pim-agentline,
.site-page--agent .pim-agentline--meta,
.site-page--agent .pim-agentline--tool,
.site-page--agent .pim-agentline--code,
.site-page--agent .pim-agentstatus,
.site-page--agent .pim-agentvoice,
.site-page--agent .pim-agentgate-note,
.site-page--agent .pim-agentgate-opt,
.site-page--agent .pim-console-tag,
.site-page--agent .pim-console-name,
.site-page--agent .pim-console-bar-title {
  font-size: 13px !important;
}

/* --- The rest of the sub-14px prose, found by auditing computed sizes -----
   The disclosure labels ("Under the hood", the audit section titles) were
   12.5px, the pricing tick rows and the case-panel definition terms 13.8, and
   the footer's legal link 13.8. */
.pim-tech-summary span,
.pim-checklist-summary .pim-checklist-label,
.pim-ticks > li > span,
.case-panel dt,
.pim-render-lines li,
.pim-footer-legal-links a {
  font-size: 14px !important;
}

/* The case pages' anchor row is navigation, so it takes the nav size. */
.case-navigation a,
.pim-anchors a {
  font-size: 15px !important;
  font-weight: 500 !important;
}

/* pass4 pins the case-index card titles at 17px with a four-class
   !important, which outranks the .pim-h3 rule above. They are card titles in
   a four-across grid, so they take the h3 size the same way the 3 Steps card
   titles do. */
.site-page--cases .case-index .pim-study .pim-h3 {
  font-size: 24px !important;
}

/* --- Buttons: a 44px target ----------------------------------------------
   site.css asks for min-height 44px, but reference-theme and pass4 each set
   38px afterwards, so buttons were rendering 31-38px. Restored, with the
   block padding removed so the min-height is what decides the box and the
   label stays centred by the flex alignment already on .pim-btn.

   The animation's own CTAs are excluded: they size in container units with
   the rest of the diagram, and a fixed 44px there would break the finale's
   spacing against the badge rows. */
.pim-btn,
.button:not(.mobile-nav-cta),
.pim-plan-cta.pim-btn,
.mobile-nav-cta {
  min-height: 44px !important;
  padding-block: 0 !important;
}

/* --- Case cards: the whole card is the link -------------------------------
   The card carried a "Read the walk" link at the bottom; the card itself is
   the target now, so that text is gone and its <a> stretches over the card
   instead. It keeps visually-hidden text naming the case, because a link
   with no accessible name is a link a screen reader cannot announce.

   Safe because each card holds exactly one link — nothing gets covered up. */
.pim-vh {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.site-page--cases .case-index .pim-study {
  position: relative;
}

/* Cover the card by clipping rather than by arithmetic. `inset: 0` on an
   absolutely positioned child of this flex card resolves against its content
   box horizontally but its padding box vertically, so compensating for the
   padding by hand got the width right and overshot the height by 19px. An
   oversized cover plus `overflow: hidden` on the card needs no measurement
   and cannot drift if the padding ever changes: the clip decides the shape,
   and a clipped region is not hit-testable, so the clickable area is exactly
   the card. The focus ring goes inside for the same reason — an outline
   outside the card would be clipped away. */
.site-page--cases .case-index .pim-study {
  overflow: hidden;
}

.site-page--cases .case-index .pim-study-cover {
  position: absolute;
  inset: -60px;
  z-index: 2;
}
/* The affordance the removed link used to provide. */
.site-page--cases .case-index .pim-study:hover {
  border-color: #9FC4F5;
  box-shadow: 0 10px 24px rgba(4, 31, 55, 0.10);
}

.site-page--cases .case-index .pim-study-cover:focus-visible {
  outline: 2px solid #0A66FF;
  outline-offset: -5px;
}

/* The headline used to sit above a link that took the slack; without it the
   card needs its own bottom padding to keep the text off the edge. */
.site-page--cases .case-index .pim-study-headline {
  margin-bottom: 0;
  padding-bottom: 4px;
}

/* v3 case intro: from the fixture to its parts -----------------------------
   The lighting case opened on the plate shot alone, which showed the product
   but not the case's own argument. It is the pair now: the fixture as it is
   sold beside the exploded view of the same fixture — the one the features
   page uses — under "From this" and "to this". The schematic is the wider of
   the two, so it gets the wider column rather than being scaled down to
   match a square photo.

   The `.editorial-media > img` rule elsewhere in this file targets a direct
   child, so it does not reach these two; they are sized here. */
.site-page--cases .case-transform-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1.55fr);
  align-items: center;
  gap: 10px;
  padding: 16px 16px 4px;
}

.site-page--cases .case-transform-step {
  min-width: 0;
}

.site-page--cases .case-transform-step img {
  display: block;
  width: 100%;
  height: auto;
}

.site-page--cases .case-transform-label {
  margin: 0 0 6px;
  color: var(--ref-blue-600);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .11em;
  text-transform: uppercase;
}

.site-page--cases .case-transform-arrow {
  margin: 14px 0 0;
  color: var(--ref-blue-600);
  font-size: 22px;
  line-height: 1;
}

/* Stacked, the arrow turns to point down the page instead of across it. */
@media (max-width: 620px) {
  .site-page--cases .case-transform-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 4px;
  }

  .site-page--cases .case-transform-arrow {
    margin: 6px 0;
    rotate: 90deg;
    justify-self: center;
  }
}

/* The pair sits on the page, not in a panel. Scoped to .case-transform so the
   other three case pages keep the card their plate shot still needs — this is
   the only intro built as two loose images.

   It works because both assets are keyed to alpha: the schematic already was,
   and the fixture photo came on its own near-white ground, which would have
   gone on reading as a white card with the card's chrome removed. */
.site-page--cases .case-intro-media .editorial-media.case-transform {
  overflow: visible;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}

.site-page--cases .case-transform-grid {
  padding: 0;
  gap: 16px;
}

/* v3 case pages: land the anchor below both sticky bars -------------------
   The case pages stack two sticky bars — the 61-65px header, and the anchor
   row sticky at top: 60px — so a target has to clear ~120px, not the 72px
   the features page needs. The case panels carry .pim-feature too, so they
   were inheriting that 72px and landing 48px underneath the anchor row.

   The row's height was the harder half: it is not breakpoint-driven, it
   wraps. Eight chips fit one 60px row at 1100px and spill to two 108px rows
   by 900px, and the wrap point differs per case page because each has its own
   chips. A single offset cannot be right for both heights, so the row is held
   to one line and scrolls sideways instead — the same thing the features rail
   already does when it runs out of width. Its height is then a constant 60px
   wherever it is sticky, and one offset covers the whole range. */
.site-page--cases .case-navigation ul {
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: thin;
}

.site-page--cases .case-navigation a {
  white-space: nowrap;
}

/* 60px of sticky offset + the row's own height + air. The row is 60px until
   it overflows, at which point a thin scrollbar is reserved and it becomes
   70px — and that happens at a different width on each case page, since each
   has its own chips. 142px clears the taller case with 12px to spare and the
   shorter one with 22px, which is cheaper than trying to breakpoint a
   content-driven number per page. */
.site-page--cases .case-panel.pim-feature {
  scroll-margin-top: 142px;
}

/* Below 640px site.css takes the row out of the flow, so only the header
   sticks and the offset drops to it. */
@media (max-width: 640px) {
  .site-page--cases .case-panel.pim-feature {
    scroll-margin-top: 80px;
  }
}

/* v3 case intro: a bare image ---------------------------------------------
   The pneumatics case now opens on the annotated cylinder — the three
   decisions and the values calculated from them, which is the case's whole
   argument — so it needs no caption explaining itself and no panel around it.
   Like the lighting pair, this only works because the asset is a cut-out on
   alpha; an opaque shot would read as a white card with the chrome removed.

   `.editorial-media > img` elsewhere in this file crops to 16/9 with
   `object-fit: contain` on a tinted ground, which would letterbox a 4/3
   drawing inside a box it does not fill. Here the image keeps its own ratio. */
.site-page--cases .case-intro-media .editorial-media.case-bare {
  overflow: visible;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}

.site-page--cases .case-intro-media .editorial-media.case-bare > img {
  aspect-ratio: auto;
  height: auto;
  object-fit: fill;
  background: none;
}

/* v3 full-size view for the dense schematics --------------------------------
   Both annotated case images carry text that only reads at their own size:
   in the intro's 672px column the ORVEX schematic renders at 47%, so its
   per-module specifications land near 7px. Clicking the image opens it at
   natural size.

   CSS only, because no JavaScript ships on this site and the CSP forbids an
   inline one. `:target` does the work: the overlay is display: none until its
   own id is the fragment, and the Close link points back at the figure's id,
   which both un-targets the overlay and returns the reader to where they
   clicked. Browser Back closes it too.

   The image inside is at its own width with `max-width: none`, and the
   overlay scrolls — so this is genuinely full resolution, not an image
   re-fitted to the viewport, which is the whole point for a diagram whose
   numbers are the content. Not marked up as a dialog: without JS there is no
   focus trap and no Escape, and claiming the role would promise both. */
.zoom-open {
  display: block;
  cursor: zoom-in;
  text-decoration: none;
}

/* Below the image, not over it. Overlaid in the corner it covered content on
   both of these — the validity checkmark on one, the extension-force box on
   the other — and there is no corner that is empty in both. */
.zoom-open-hint {
  display: block;
  margin-top: 8px;
  color: var(--ref-blue-600);
  font-family: var(--pim-font-sans);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: .01em;
  text-align: right;
  transition: color 0.15s ease;
}

.zoom-open:hover .zoom-open-hint,
.zoom-open:focus-visible .zoom-open-hint {
  color: #0A66FF;
  text-decoration: underline;
}

.zoom-open:focus-visible {
  outline: 2px solid #0A66FF;
  outline-offset: 3px;
}

.zoom-view {
  display: none;
}

.zoom-view:target {
  display: block;
  position: fixed;
  inset: 0;
  z-index: 200;
  overflow: auto;
  padding: 56px 24px 40px;
  background: rgba(3, 24, 44, 0.95);
  overscroll-behavior: contain;
}

.zoom-view:target > img {
  display: block;
  width: auto;
  max-width: none;
  height: auto;
  margin: 0 auto;
  border-radius: 4px;
  background: #fff;
}

.zoom-view-close {
  position: fixed;
  top: 14px;
  right: 20px;
  z-index: 1;
  padding: 0 16px;
  min-height: 40px;
  display: inline-flex;
  align-items: center;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 4px;
  background: rgba(3, 24, 44, 0.9);
  color: #fff;
  font-family: var(--pim-font-sans);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
}

.zoom-view-close:hover {
  border-color: #fff;
  background: #0A66FF;
}

/* On a phone the natural width is far past the viewport, so it scrolls both
   ways; the hint says so rather than looking like a broken layout. */
@media (max-width: 620px) {
  .zoom-view:target {
    padding: 52px 12px 32px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .zoom-open-hint { transition: none; }
}

/* v3 finale CTAs at the site's button height ------------------------------
   These were left on the diagram's container-unit scale, which made them
   27-34px tall depending on viewport — the only buttons on the site under
   44px, and smallest exactly where a touch target matters most. They take
   the 44px now, which costs 10px of height at 1600 and 16px at 820.

   The finale had no room for that: measured with the animations cancelled
   (base styles here are the finished state), the tagline block sat 8.5px
   below the logo's lower square at 1600 and 2.5px at 820, and its own bottom
   was 0.3px off the stage edge. Growing it symmetrically would have driven it
   into the logo.

   So the space is found rather than taken. The block's own padding comes down
   from 1.0cqw to 0.4cqw and the CTA row's margin from 0.85cqw to 0.55cqw,
   which together give back more than the buttons take at wide widths, and the
   block's centre moves from 87% to 88.5% so what growth remains goes
   downward. Downward is free: the stage is overflow: visible and the hero
   keeps 28px of padding below it before the next section. */
.home-hero .pim-flow-outro-copy {
  top: 88.5%;
  padding-block: 0.4cqw;
}

.home-hero .pim-flow-outro-actions {
  margin-top: 0.55cqw;
}

/* The shorter the stage, the less the reclaimed space buys: at 660px the block
   came within 1.3px of the logo's lower square, and under 640px it clipped it.
   It drops another 2% from 820px down, which leaves at least 6px above and
   about 10px below at every width measured — the hero has 28px of padding to
   spend there. */
@media (max-width: 820px) {
  .home-hero .pim-flow-outro-copy {
    top: 90.5%;
  }
}

/* And once more below 620px. The clearance above falls about 0.04px for every
   px of viewport lost — 7.7px at 640, 1.9px at 500 — so extrapolating, a real
   phone would have clipped the square again. */
@media (max-width: 620px) {
  .home-hero .pim-flow-outro-copy {
    top: 92%;
  }
}

/* Trimming the block's padding above also trimmed its scrim, which is inset
   from the block and so lost 1.2cqw of vertical reach — the fade had less
   room to happen in and the box read harder-edged. The scrim gets that reach
   back on its own inset, which is negative on an absolutely positioned
   ::before and so costs the layout nothing: the collision clearances measured
   above are the block's border box, not this. */
.home-hero .pim-flow-outro-copy::before {
  inset: -1.0cqw -1.2cqw;
  /* The block reads as a card, so it gets a card's corners. The mask has to
     give way for that: at a 62% plateau it faded the corners out entirely and
     a radius under it was invisible. Widened to 108% x 150% with the plateau
     at 86%, which keeps the fill solid across the panel — so the radius is
     what shapes it — while the outermost edge still softens rather than
     ending on a line against the animation behind it. */
  border-radius: 14px;
  -webkit-mask-image: radial-gradient(ellipse 108% 150% at 50% 50%, #000 0%, #000 86%, transparent 100%);
  mask-image: radial-gradient(ellipse 108% 150% at 50% 50%, #000 0%, #000 86%, transparent 100%);
}
