/* PIM-TNG marketing site — one dark surface, lifted from the app's /flow page.

   The palette is not invented here: every token below is a colour already on
   screen in assets/data_flow.css, so the landing intro and the pages under it
   are the same object. There is no light theme on purpose — the product's front
   door is a starfield, and a second palette would be a second thing to keep
   true.

   Layer order: tokens, base, typography, controls, layout, components, then the
   per-page blocks. flow.css owns the hero diagram and nothing else. */

/* —— Typefaces ——
   Self-hosted for the same reason the app self-hosts: deployments must not
   depend on a font CDN, and the site makes no external request at all. All
   three notices are in static/fonts/LICENSES.md.

   IBM Plex Sans (SIL OFL 1.1) carries the body text and every word of prose.
   It is already vendored in this monorepo as static TTFs the app itself
   serves from assets/fonts/ -- Regular and Medium -- so the site reuses those
   exact files rather than fetching its own copy, just subset and converted to
   woff2. Two files because IBM Plex Sans ships as static weights, not a
   variable font: one @font-face per weight, both named "IBM Plex Sans" so the
   browser picks the right file for font-weight: 400 vs 500.

   Manrope (SIL OFL 1.1) carries the headings, its own family rather than an
   alias of the body face so the two can move independently. It is not vendored
   anywhere else in the repo, so it was fetched from Google Fonts' source
   repository for this site alone. One file: it is the variable `wght` axis
   (200-800), so every heading weight comes out of the same download. It
   replaced Roboto Condensed, whose files were deleted rather than left in the
   tree -- an unreferenced 81 KB face is exactly the dead weight the rest of
   this comment is about.

   Both are subset to latin + latin-ext with fonttools -- latin-ext because the
   planned es.json locale needs it -- and committed, so the build still needs
   nothing but Jinja2. Being physically subset was once the reason no
   unicode-range was needed here; it was also the reason Bulgarian rendered in
   the system UI font, because a subset font gives the browser nothing to fall
   back *from*. The Cyrillic companions below fix that, and they are the only
   faces here that carry a range.

   woff2 rather than the app's TTF, because this is a landing page where the
   first paint is the product: the four latin files are 21,592 / 24,388 /
   32,344 and 16,036 bytes, ~94 KB of font for a page in English or Catalan.
   Bulgarian adds the three Cyrillic companions and Tektur, ~48 KB more, and
   only for Bulgarian. */
@font-face {
  font-family: "PIM Display";
  src: url("../fonts/Orbitron-VariableFont_wght.woff2") format("woff2-variations");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans";
  src: url("../fonts/IBMPlexSans-Regular-subset.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
/* Cyrillic ------------------------------------------------------------------
   The latin files above are physically subset, which is why Bulgarian needed
   these: a subset font has no unicode-range to fall back *from*, so the browser
   reaches past it to the system UI face one glyph at a time and a sentence
   mixing Cyrillic with a product name comes out in two typefaces. The companion
   files below carry a Cyrillic unicode-range, so an English or Catalan visitor
   never requests them -- the whole change costs those pages nothing.

   Declared after their latin sibling on purpose: both faces of a family are
   candidates for a codepoint (an @font-face without unicode-range means all of
   them), and the last declaration wins, so the ranged one has to come second.

   Built by webpage/subset_fonts.py, which also prints these ranges. They are
   what the files really cover, not what the range is called: promising a
   codepoint the file lacks makes the browser fetch it and fall back anyway. */
@font-face {
  font-family: "IBM Plex Sans";
  src: url("../fonts/IBMPlexSans-Regular-cyrillic.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "IBM Plex Sans";
  src: url("../fonts/IBMPlexSans-Medium-subset.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans";
  src: url("../fonts/IBMPlexSans-Medium-cyrillic.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Manrope";
  src: url("../fonts/Manrope-VariableFont_wght.woff2") format("woff2-variations");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Manrope";
  src: url("../fonts/Manrope-cyrillic.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0400-045F, U+0490-0491, U+2116;
}
/* The Bulgarian stand-in for Orbitron ---------------------------------------
   Orbitron has no Cyrillic and cannot get any: upstream ships one `latin`
   subset and that is the entire font. Tektur is the nearest face on Google
   Fonts to what Orbitron is doing in the intro -- squarish, flat-sided,
   monoline, a machine label rather than prose -- and it has Cyrillic plus the
   Bulgarian locl forms. It carries latin as well as Cyrillic, so a Bulgarian
   label reading "XLSX" or "PIM-TNG" stays in one face instead of straddling
   two. Nothing references this family except the one rule in flow.css, so no
   other locale downloads it. wdth is pinned to 100 in the subset: the site sets
   a weight and nothing else. */
@font-face {
  font-family: "PIM Display BG";
  src: url("../fonts/Tektur-subset.woff2") format("woff2-variations");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Ink: the page gradient, top to bottom. */
  --pim-ink-1: #0b1e46;
  --pim-ink-2: #081634;
  --pim-ink-3: #050e24;
  --pim-glow-core: rgba(56, 132, 255, 0.22);
  --pim-glow-arc: #16407f;

  /* Light: accent, glow and the two hairline weights. */
  --pim-spark: #9beaff;
  --pim-halo: rgba(79, 195, 255, 0.45);
  --pim-line: rgba(122, 176, 255, 0.26);
  --pim-edge: rgba(127, 199, 255, 0.35);

  /* Type. */
  --pim-text: #0c1f37;
  --pim-text-dim: #5e6e82;
  --pim-text-icon: #176fbf;

  /* Surfaces, from the diagram's node tiles. */
  --pim-surface: #ffffff;
  --pim-surface-flat: #f7f9fc;

  /* The nine roster pastels. One per capability, kept in the same order the
     intro drops them, and reused wherever a section needs an identity. */
  --pim-tone-lilac: #d9c2ff;
  --pim-tone-plum: #e8bce6;
  --pim-tone-mint: #a8ecd0;
  --pim-tone-sky: #a9dcff;
  --pim-tone-peach: #ffd3a8;
  --pim-tone-gold: #f4e3a6;
  --pim-tone-aqua: #9de6e8;
  --pim-tone-sage: #c8e6a8;
  --pim-tone-rose: #ffc2d6;
  /* Default for anything not given a tone. */
  --pim-tone: var(--pim-text-icon);

  /* Faces. IBM Plex Sans carries every word of prose and every button; Manrope
     carries every heading, kept as its own family (not an alias of `sans`)
     because the two are meant to move independently.

     Orbitron survives as `brand`, and only two places may spend it: the
     wordmark, and the flow diagram's own node and badge labels. The diagram is
     a deliberate fork of the app's /flow page and those tiny uppercase words
     ("ERP", "XLSX", "PDF") are machine chrome inside a picture -- nobody reads
     them as a sentence. Everything that is actually read is IBM Plex Sans or
     Manrope. */
  --pim-font-brand: "PIM Display", ui-sans-serif, system-ui, sans-serif;
  --pim-font-sans: "IBM Plex Sans", ui-sans-serif, system-ui, sans-serif;
  --pim-font-display: "Manrope", ui-sans-serif, system-ui, sans-serif;

  /* Type scale. Four sizes, and copy may use nothing else -- the page used to
     carry about thirty ad-hoc values between 0.92rem and 0.97rem, which is how
     a 17px body ended up reading as small: every card, note and definition
     list quietly shaved a point off it. The root is 18px (see `html` below),
     so 1rem is 18px here and 17px inside the narrow-screen block.

     `desc` is the "slightly smaller for descriptions" the review asked for;
     `meta` is for footnotes and legal lines, which are not reading copy. UI
     chrome -- buttons, nav, eyebrows, pills, the anchor rail -- is deliberately
     outside this scale and keeps its own smaller sizes. */
  --pim-fs-body: 1rem;
  --pim-fs-desc: 0.95rem;
  --pim-fs-meta: 0.86rem;
  --pim-fs-lede: clamp(1.12rem, 1.6vw, 1.28rem);
  /* Longest comfortable line for prose that is not already boxed by a grid. */
  --pim-measure: 68ch;

  /* Spacing. A ~1.45x ramp, so the section, card and heading rhythm comes from
     one place instead of thirty rem values that were each chosen alone. Step 7
     is the band, step 6 the band on a phone and the gap under a section
     heading, step 4 the padding inside a card; the bottom two are gaps within
     a component.

     The values look unround because they are pinned to pixels at the 18px root
     (≈10 / 15 / 22 / 32 / 47 / 65 / 112), not to the old 16px one. Written
     round they would have inflated every gap by another eighth on top of the
     increase this pass is actually making. */
  --pim-space-1: 0.55rem;
  --pim-space-2: 0.85rem;
  --pim-space-3: 1.25rem;
  --pim-space-4: 1.75rem;
  --pim-space-5: 2.6rem;
  --pim-space-6: 3.6rem;
  --pim-space-7: 6.2rem;

  --pim-shell: 1160px;
  --pim-radius: 14px;
}

.pim-tone--lilac { --pim-tone: var(--pim-tone-lilac); }
.pim-tone--plum { --pim-tone: var(--pim-tone-plum); }
.pim-tone--mint { --pim-tone: var(--pim-tone-mint); }
.pim-tone--sky { --pim-tone: var(--pim-tone-sky); }
.pim-tone--peach { --pim-tone: var(--pim-tone-peach); }
.pim-tone--gold { --pim-tone: var(--pim-tone-gold); }
.pim-tone--aqua { --pim-tone: var(--pim-tone-aqua); }
.pim-tone--sage { --pim-tone: var(--pim-tone-sage); }
.pim-tone--rose { --pim-tone: var(--pim-tone-rose); }

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

/* The base size lives on `html`, not on `body`, and that is the whole reason
   the scale works: `rem` resolves against the root element, so setting it on
   `body` would leave every `rem` in this file -- all four type tokens and the
   whole spacing ramp -- still measured against the browser's 16px default. It
   is a percentage rather than 18px so a reader who has raised their browser's
   default still gets a proportionally larger page. */
html {
  scroll-behavior: smooth;
  font-size: 112.5%; /* 18px at a default 16px browser setting */
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--pim-font-sans);
  line-height: 1.65;
  color: var(--pim-text);
  -webkit-font-smoothing: antialiased;
  background: #ffffff;
}

/* Star field: two repeating tiles at different sizes so the grid never reads.
   Fixed rather than absolute, so it stays put behind a scrolling page instead
   of ending with the first screen. */
body::before,
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  display: none;
}

body::before {
  background-image:
    radial-gradient(1.2px 1.2px at 24px 32px, rgba(255, 255, 255, 0.9), transparent 60%),
    radial-gradient(1px 1px at 116px 78px, rgba(198, 226, 255, 0.75), transparent 60%),
    radial-gradient(1.7px 1.7px at 168px 22px, rgba(255, 255, 255, 0.95), transparent 60%),
    radial-gradient(1px 1px at 68px 148px, rgba(178, 212, 255, 0.7), transparent 60%);
  background-size: 210px 190px;
  opacity: 0.5;
}

body::after {
  background-image:
    radial-gradient(1px 1px at 40px 96px, rgba(255, 255, 255, 0.8), transparent 60%),
    radial-gradient(1.4px 1.4px at 232px 44px, rgba(160, 205, 255, 0.85), transparent 60%),
    radial-gradient(1px 1px at 150px 210px, rgba(255, 255, 255, 0.6), transparent 60%);
  background-size: 320px 280px;
  opacity: 0.35;
  animation: pim-twinkle 7s ease-in-out infinite alternate;
}

@keyframes pim-twinkle {
  from { opacity: 0.2; }
  to { opacity: 0.45; }
}

/* Everything real sits above the star field. */
.pim-header,
main,
.pim-footer { position: relative; z-index: 1; }

img { max-width: 100%; height: auto; }

a { color: var(--pim-spark); }

:focus-visible {
  outline: 2px solid var(--pim-spark);
  outline-offset: 3px;
  border-radius: 4px;
}

.pim-skip {
  position: absolute;
  left: 50%;
  top: 0;
  translate: -50% -120%;
  z-index: 20;
  padding: 0.6rem 1.1rem;
  background: var(--pim-ink-1);
  border: 1px solid var(--pim-edge);
  border-radius: 0 0 10px 10px;
  text-decoration: none;
}

.pim-skip:focus { translate: -50% 0; }

.pim-shell {
  width: 100%;
  max-width: var(--pim-shell);
  margin-inline: auto;
  padding-inline: 1.5rem;
}

.pim-icon { width: 1.5rem; height: 1.5rem; }
.pim-icon--inline { width: 1em; height: 1em; vertical-align: -0.12em; }
.pim-icon--tick { width: 1.05em; height: 1.05em; flex: none; margin-top: 0.42em; color: var(--pim-tone); }

/* —— Typography ———————————————————————————————————————————————————————
   Orbitron used to take the headings, the labels and the pills. It is a wide
   geometric display face, and at heading size next to Roboto body copy the
   whole page read as an instrument panel rather than as writing. So the
   headings and the labels came back to the text face: they keep the treatment
   that actually signalled "chrome" -- uppercase, tracked out, small -- which
   never needed a second family to work.

   Only the wordmark still spends Orbitron. It is a logo, and a logo is allowed
   to be a different object from the page it sits on. */
.pim-h1,
.pim-h2,
.pim-h3,
.pim-eyebrow,
.pim-pill,
.pim-footer-heading,
.pim-end-heading,
.pim-anchors a,
.pim-deflist dt {
  font-family: var(--pim-font-display);
}

/* Buttons are the one piece of chrome set in the body face rather than the
   heading one: a button is a thing you are about to do, not a title, and at
   0.86rem uppercase with 0.08em tracking IBM Plex Sans is the more legible of
   the two. Written out rather than left to inherit from `body`, because the
   selector above is where a reader looks to find out what a button is set in. */
.pim-btn {
  font-family: var(--pim-font-sans);
}

.pim-brand span { font-family: var(--pim-font-brand); }

/* Letter-spacing pulled back by hand, more at h1 than at h2 because the error
   grows with the size. Checked at both ends of the clamp: the h1 minimum
   (2.3rem, phones) still has daylight between the letters. */
.pim-h1 {
  margin: 0 0 1rem;
  font-size: clamp(2.3rem, 5.2vw, 3.9rem);
  font-weight: 800;
  line-height: .97;
  letter-spacing: -0.045em;
  text-wrap: balance;
}

.pim-h2 {
  margin: 0 0 0.75rem;
  font-size: clamp(1.6rem, 3vw, 2.3rem);
  font-weight: 800;
  line-height: .98;
  letter-spacing: -0.045em;
  text-wrap: balance;
}

.pim-h3 {
  margin: 0 0 0.4rem;
  font-size: 1.06rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--pim-text);
}

.pim-eyebrow {
  margin: 0 0 0.7rem;
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--pim-tone);
  text-shadow: 0 0 14px color-mix(in srgb, var(--pim-tone) 40%, transparent);
}

.pim-lede {
  margin: 0;
  color: var(--pim-text-dim);
  font-size: var(--pim-fs-lede);
  line-height: 1.6;
  max-width: 62ch;
}

/* The line under a hero lede, for the page whose lede is the one sentence it
   exists to say and which then needs a paragraph of explanation. Body size, dim:
   it must not read as a second lede. */
.pim-hero-support {
  margin: var(--pim-space-3) 0 0;
  color: var(--pim-text-dim);
  font-size: var(--pim-fs-body);
  line-height: 1.6;
  max-width: var(--pim-measure);
}

/* The studies index's intro: the heading block, and the disclaimer that
   qualifies the cards under it, wrapped so the space between them can be spent
   deliberately. The heading gives up its own bottom margin in here and the
   wrapper carries it instead, which puts the footnote a short step under the
   sentence it follows and a full section step above the grid. That is the
   opposite way round from where a negative margin had left it -- 65px under the
   lede and flush against the cards, so it read as a caption on the grid rather
   than as a note on the sentence. */
.pim-studies-intro { margin-bottom: var(--pim-space-6); }
.pim-studies-intro .pim-heading { margin-bottom: var(--pim-space-2); }

/* The disclaimer itself. Dim and small: it reads at the weight of the legal
   line in the footer, because it is a qualifier and not part of the argument.
   Narrower measure than the lede above it, so it still looks like a footnote
   rather than another paragraph. */
.pim-case-note {
  margin: 0;
  max-width: 74ch;
  color: var(--pim-text-dim);
  font-size: var(--pim-fs-meta);
  line-height: 1.6;
  opacity: 0.85;
}

/* Only the measure changes. The wide lede used to also be a size of its own,
   which made two ledes on one page two different sizes for no reason; the
   clamp covers what that override was reaching for. */
.pim-lede--wide { max-width: 74ch; }

.pim-note {
  margin: 1.6rem 0 0;
  color: var(--pim-text-dim);
  font-size: var(--pim-fs-meta);
  line-height: 1.6;
  max-width: var(--pim-measure);
}

.pim-heading { margin-bottom: var(--pim-space-6); }

/* The one section whose heading reads as a centred statement rather than a
   left-aligned title -- "3 Steps" over three step bands that already repeat
   their own names, so the heading's job shrank to a single short fact and it
   is set like one. */
.pim-heading--center { text-align: center; }

p { margin: 0 0 0.9rem; }
p:last-child { margin-bottom: 0; }

.pim-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin-top: 0.9rem;
  /* Set with the copy it follows rather than shrunk like a button: it is a
     sentence with an arrow on it, and it was reading as a caption. */
  font-size: var(--pim-fs-desc);
  font-weight: 500;
  text-decoration: none;
  color: var(--pim-tone);
}

.pim-link:hover { text-decoration: underline; }
.pim-link .pim-icon { transition: translate 0.18s ease; }
.pim-link:hover .pim-icon { translate: 3px 0; }

/* —— Controls —————————————————————————————————————————————————————————— */
.pim-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: var(--pim-space-4);
}

.pim-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.72rem 1.35rem;
  border-radius: 4px;
  border: 1px solid var(--pim-edge);
  font-size: 0.86rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--pim-text);
  background: rgba(18, 42, 92, 0.55);
  transition: box-shadow 0.2s ease, translate 0.2s ease, background 0.2s ease;
}

.pim-btn:hover {
  translate: 0 -1px;
  box-shadow: 0 0 24px rgba(79, 195, 255, 0.28);
}

.pim-btn--primary {
  color: #fff;
  border-color: transparent;
  background: linear-gradient(180deg, #289cff, #137fe0);
  box-shadow: 0 8px 22px rgba(24,133,230,.22);
}

.pim-btn--primary:hover { box-shadow: 0 0 42px rgba(120, 220, 255, 0.55); }

.pim-btn--ghost { background: transparent; }
.pim-btn--ghost:hover { background: rgba(30, 62, 122, 0.45); }

.pim-btn--lg { padding: 0.9rem 1.7rem; font-size: 0.95rem; }

/* —— Header and footer ————————————————————————————————————————————————— */
.pim-header {
  position: sticky;
  top: 0;
  z-index: 10;
  border-bottom: 1px solid var(--pim-line);
  background: rgba(4,22,43,.97);
  backdrop-filter: blur(10px);
}

.pim-header-inner {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  min-height: 68px;
}

.pim-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 700;
  font-size: 1.02rem;
  letter-spacing: 0.12em;
  text-decoration: none;
  color: #fff;
}

.pim-nav {
  display: flex;
  gap: 0.35rem;
  margin-inline-start: auto;
  flex-wrap: wrap;
}

.pim-nav a {
  padding: 0.45rem 0.85rem;
  border-radius: 3px;
  font-size: 0.92rem;
  text-decoration: none;
  color: #c9d8e7;
}

.pim-nav a:hover { color: var(--pim-text); background: rgba(30, 62, 122, 0.5); }

.pim-nav a[aria-current="page"] {
  color: #fff;
  background: rgba(32,140,241,.16);
  box-shadow: inset 0 -2px #208cf1;
}

.pim-header-cta { padding: 0.5rem 1.05rem; font-size: 0.78rem; }

/* Language switcher --------------------------------------------------------
   A disclosure rather than a row of codes: the header costs the same at two
   languages as at ten, and the panel has room for endonyms, which is the point
   -- "Deutsch" is scannable in a list of ten and "DE" is not.

   Sized and coloured like the EU badge in the footer rather than like a nav
   link: a reader who wants their own language goes looking for it, so it does
   not need to compete with the things a visitor came to click. It fills the
   third grid column, spare since the sign-in slot was dropped, which is why
   this is justify-self rather than a margin and why the nav does not move. */
.pim-langs {
  position: relative;
  justify-self: end;
}

.pim-langs-summary {
  display: inline-flex;
  align-items: center;
  gap: 0.34rem;
  padding: 0.32rem 0.5rem;
  border-radius: 3px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #8fa7bc;
  cursor: pointer;
  /* Both, because the two engines hide the default marker differently. */
  list-style: none;
}

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

.pim-langs-summary:hover,
.pim-langs[open] .pim-langs-summary { color: #fff; background: rgba(30, 62, 122, 0.5); }

.pim-langs-summary .pim-icon { width: 14px; height: 14px; flex: none; }

/* Drawn rather than a glyph: it is a state indicator for the control beside it,
   not an icon in its own right, and it has to rotate. */
.pim-langs-cue {
  width: 0;
  height: 0;
  border-inline: 3px solid transparent;
  border-top: 4px solid currentColor;
  transition: transform 0.15s ease;
}

.pim-langs[open] .pim-langs-cue { transform: rotate(180deg); }

.pim-langs-list {
  position: absolute;
  right: 0;
  top: calc(100% + 0.4rem);
  z-index: 60;
  margin: 0;
  padding: 0.3rem;
  list-style: none;
  min-width: 10rem;
  /* The ten-language provision: the panel scrolls rather than running off the
     bottom of a phone. */
  max-height: min(60vh, 22rem);
  overflow-y: auto;
  border: 1px solid rgba(129, 184, 232, 0.28);
  border-radius: 5px;
  background: #061d34;
  box-shadow: 0 14px 34px rgba(2, 14, 28, 0.45);
}

.pim-langs-list a {
  display: block;
  padding: 0.45rem 0.7rem;
  border-radius: 3px;
  font-size: 0.85rem;
  font-weight: 500;
  letter-spacing: 0;
  text-decoration: none;
  white-space: nowrap;
  color: #c9d8e7;
}

.pim-langs-list a:hover { color: #fff; background: rgba(30, 62, 122, 0.6); }

.pim-langs-list a[aria-current="true"] {
  color: #fff;
  background: rgba(32, 140, 241, .16);
  box-shadow: inset 0 -2px #208cf1;
}

/* A quiet trust badge, not another nav item: smaller and dimmer than the links
   beside it, because a hosting fact is not something to compete with the
   things a visitor actually came to click. The flag's own colours are real
   ones (Pantone reflex blue, the EU's gold) rather than tokens, the same way a
   flag on a form doesn't get skinned to a site's palette. */
.pim-eu-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  flex: none;
  font-size: 0.76rem;
  letter-spacing: 0.02em;
  color: var(--pim-text-dim);
  white-space: nowrap;
}

.pim-footer-brand .pim-eu-badge { margin-top: 0.9rem; }

.pim-eu-flag {
  width: 18px;
  height: 18px;
  flex: none;
}

.pim-eu-flag circle { fill: #039; }
.pim-eu-flag use { fill: #fc0; }

.pim-footer {
  border-top: 1px solid var(--pim-line);
  background: rgba(5, 14, 36, 0.72);
  padding-block: var(--pim-space-5) var(--pim-space-3);
}

.pim-footer-inner {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: var(--pim-space-5);
}

.pim-footer-brand p {
  margin-top: 0.9rem;
  color: var(--pim-text-dim);
  font-size: var(--pim-fs-desc);
  line-height: 1.6;
  max-width: 42ch;
}

.pim-footer-heading {
  margin: 0 0 0.9rem;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pim-text-icon);
}

.pim-footer-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.5rem;
  font-size: var(--pim-fs-desc);
}

.pim-footer-list a { color: var(--pim-text-dim); text-decoration: none; }
.pim-footer-list a:hover { color: var(--pim-spark); }

.pim-footer-legal {
  /* Flex rather than a block: the row carries the copyright and the footer-only
     links, which sit at opposite ends on a wide screen and stack on a phone.
     `wrap` plus a gap is what makes that one rule instead of a media query. */
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--pim-space-2);
  margin-top: var(--pim-space-5);
  padding-top: var(--pim-space-3);
  border-top: 1px solid var(--pim-line);
  color: var(--pim-text-dim);
  font-size: var(--pim-fs-meta);
}

.pim-footer-legal-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--pim-space-1) var(--pim-space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.pim-footer-legal-links a {
  color: var(--pim-text-dim);
  text-decoration: none;
}

.pim-footer-legal-links a:hover {
  color: var(--pim-text);
  text-decoration: underline;
}

/* —— Sections and grids ————————————————————————————————————————————————
   The band padding is the page's largest interval on purpose: with 5rem the
   review read the whole document as one continuous wall, because the space
   between two sections was barely more than the space inside one. 7rem makes
   the section the unit you see first. */
.pim-section { padding-block: var(--pim-space-7); }

/* The features page's outer section: its first child is the sticky anchor
   rail, not prose, so the usual 112px of top air just pushed the one thing
   that actually navigates the page down behind an empty gap on first load --
   scrolling even a little snapped it to the top under the header anyway, so
   the gap only existed for the initial screenful. Bottom padding is
   untouched; it is still a section and still needs to breathe into whatever
   follows it. */
.pim-section--nav-top { padding-top: 0; }

/* Alternating bands: a wash and two hairlines, so the rhythm reads without a
   second background colour fighting the starfield. */
.pim-section--alt {
  background: #f5f8fc;
  border-block: 1px solid var(--pim-line);
}

/* 3rem, not the 5.5rem this used to open with. The agent page had overridden it
   to 3rem for itself, which left every other hero starting two and a half
   centimetres lower than that one -- a difference you see immediately when you
   move between tabs in the header, because the eyebrow and the title jump. The
   agent page's value was the better one, so it is the only one now. */
.pim-pagehero {
  padding-block: 3rem 3.5rem;
  border-bottom: 1px solid var(--pim-line);
  color: #fff;
  background-color: var(--pim-ink-1);
  background-image: linear-gradient(rgba(76,158,222,.065) 1px, transparent 1px), linear-gradient(90deg, rgba(76,158,222,.065) 1px, transparent 1px), linear-gradient(145deg,#04162b,#071f3d 65%,#0a2b50);
  background-size: 44px 44px, 44px 44px, auto;
}
.pim-pagehero .pim-h1 { color: #fff; }
.pim-pagehero .pim-lede, .pim-pagehero .pim-hero-support { color: #c0d1e1; }

/* The agent page's hero still flows straight into "Pick a job..." with no
   divider or gap -- it reads as one intro block, not two sections that happen
   to be adjacent. Only the bottom of it is special now; the top is what every
   page does. */
.pim-page--agent .pim-pagehero {
  padding-bottom: 0;
  border-bottom: none;
}

/* A hero whose whole content is one eyebrow-sized title -- the Pricing page.
   It keeps the shared top padding, so its title sits on the same line as every
   other page's, and gives back most of the bottom: 3.5rem under a display h1 is
   proportionate, under one small line it is a hole.

   No hairline either. The rule earns its place under a hero that is a title, a
   lede and sometimes two buttons -- it closes a block. Under a single label it
   closes nothing, and drawing a full-width line two centimetres beneath one
   small word makes the word look like a table header for the cards rather than
   the name of the page.

   The margin reset is because .pim-eyebrow normally has a heading under it to
   space itself from, and here it is the heading. */
.pim-pagehero--label {
  padding-bottom: var(--pim-space-3);
  border-bottom: none;
}

.pim-pagehero--label .pim-eyebrow { margin-bottom: 0; }
.pim-page--agent #does {
  padding-top: 0;
}

/* Same call on the case studies. On the index the rule separated the entry copy
   from the four cards it introduces, which are one thought; on a study it fell
   between the hero and the sticky beat rail, where the features page already
   found a divider plus a gap was only ever in the way. */
.pim-page--cases .pim-pagehero { border-bottom: none; }

/* With the rule gone, the hero's 63px and the section's 112px stacked into
   210px of nothing between the entry copy and the heading it introduces --
   which reads as a missing section rather than as breathing room. The hero
   keeps its own padding, so a study page (whose next block is the sticky beat
   rail at padding-top: 0) is unaffected; only the index's studies section gives
   its top padding up. Same shape as .pim-page--agent #does above. */
.pim-page--cases #studies { padding-top: 0; }

.pim-grid {
  display: grid;
  gap: var(--pim-space-3);
}

.pim-grid--3 { grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); }
/* Two cards that are each an answer to "which half of this is for me": a wider
   floor than the roster grid, so they never fall to three-across. */
.pim-grid--2 { grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); }
.pim-grid--stretch { align-items: stretch; }

/* —— Cards ————————————————————————————————————————————————————————————— */
.pim-card {
  position: relative;
  padding: var(--pim-space-4);
  border-radius: 4px;
  border: 1px solid #dce5ef;
  background: var(--pim-surface);
  box-shadow: 0 18px 45px rgba(8,27,52,.08);
  overflow: hidden;
  transition: border-color 0.2s ease, box-shadow 0.2s ease, translate 0.2s ease;
}

/* The tone shows as a lit top edge rather than a coloured card: nine pastel
   panels on one screen would be a paint chart. */
.pim-card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--pim-tone), transparent);
  opacity: 0.65;
}

.pim-card:hover {
  translate: 0 -2px;
  border-color: color-mix(in srgb, var(--pim-tone) 55%, transparent);
  box-shadow: 0 0 34px color-mix(in srgb, var(--pim-tone) 16%, transparent);
}

.pim-card p {
  color: var(--pim-text-dim);
  font-size: var(--pim-fs-desc);
  line-height: 1.6;
}

.pim-card-glyph {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin-bottom: 1.1rem;
  border-radius: 4px;
  color: var(--pim-tone);
  background: #eaf5ff;
  border: 1px solid #cae4fb;
  box-shadow: none;
}

.editorial-media { margin: 0 0 1.2rem; border: 1px solid var(--pim-line); background: #f7f9fc; padding: .75rem; }
.editorial-media > img { display: block; width: 100%; max-height: 220px; object-fit: contain; }
.editorial-media figcaption { margin-top: .65rem; color: var(--pim-text-dim); font-size: .74rem; line-height: 1.45; }
.editorial-gallery { display: grid; grid-template-columns: repeat(4, 1fr); gap: .4rem; margin-top: .65rem; }
.editorial-gallery figure { margin: 0; min-width: 0; }
.editorial-gallery img { width: 100%; height: auto; aspect-ratio: 1; object-fit: contain; background: #fff; border: 1px solid var(--pim-line); }
.editorial-gallery figcaption { font-size: .62rem; margin-top: .25rem; }
.home-workflow-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.25rem; }
.home-workflow-card { display: flex; flex-direction: column; min-height: 320px; padding: 2rem 2.1rem 1.5rem; background: #fff; }
.home-workflow-card { border: 1px solid var(--pim-line); }
.home-workflow-step { color: #edf2f7; -webkit-text-fill-color: transparent; -webkit-text-stroke: 1px #c8d5e2; font-family: "DejaVu Sans Condensed", "Arial Narrow", sans-serif; font-size: 4.1rem; line-height: .9; font-weight: 800; letter-spacing: -.06em; }
.home-workflow-rule { width: 24px; height: 2px; margin: 1.1rem 0 .85rem; background: #208cf1; }
.home-workflow-card .pim-h2 { margin: 0; font-size: 1.45rem; letter-spacing: .04em; text-transform: uppercase; }
.home-workflow-card > p { color: var(--pim-text-dim); max-width: 34ch; margin: .8rem 0 0; font-size: .86rem; line-height: 1.6; }
.home-workflow-visual { display: grid; place-items: center; min-height: 78px; margin: auto 0 .65rem; color: #208cf1; }
.home-workflow-visual svg { width: min(100%, 150px); height: 70px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
.home-workflow-link { display: grid; place-items: center start; align-self: flex-start; width: 44px; height: 44px; margin-top: auto; color: #0b80dd; font-size: 1.35rem; line-height: 1; text-decoration: none; }
.home-workflow-link:hover { color: #04162b; }
.case-editorial { display: grid; grid-template-columns: minmax(0, 1fr) minmax(220px, .55fr); align-items: center; gap: 2rem; padding-block: 2rem; }
.case-editorial .editorial-media { margin: 0; }
.trust-editorial { padding-block: 1.5rem 0; }
.trust-editorial .editorial-media { max-width: 520px; margin-inline: auto; }
.pim-study .editorial-media { margin: -1rem -1rem 1.1rem; border-width: 0 0 1px; }
.case-grid.pim-studies { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 820px) {
  .case-grid.pim-studies { grid-template-columns: 1fr; }
  .case-editorial { grid-template-columns: 1fr; gap: 1rem; }
  .editorial-gallery { gap: .25rem; }
}

/* Compact cards: the glyph sits beside the title instead of above it, which is
   one whole row a grid of these does not have to pay for. Padding shrinks with
   it -- the point was a smaller box, not just a rearranged one. */
.pim-card--compact { padding: var(--pim-space-3); }

.pim-card-title {
  display: flex;
  align-items: center;
  gap: var(--pim-space-2);
  margin-bottom: var(--pim-space-2);
}

.pim-card-title .pim-card-glyph {
  width: 36px;
  height: 36px;
  margin-bottom: 0;
  flex: none;
}

.pim-card-title .pim-h3 { margin: 0; }

/* A status marker for the rare card that needs one -- "In Beta" today, nothing
   else. Absolutely positioned across the top-right corner and rotated, so it
   costs the card's flow nothing; `.pim-card`'s own `overflow: hidden` is what
   clips the strip to the rounded corner instead of letting it hang off the
   edge. Gold rather than a new colour: it is already the roster's caution
   pastel, so this reads as "look twice" without adding a colour that means
   nothing else on the page. */
.pim-card-ribbon {
  position: absolute;
  top: 0.9rem;
  right: -2.35rem;
  width: 9rem;
  padding: 0.3rem 0;
  transform: rotate(45deg);
  text-align: center;
  font-family: var(--pim-font-brand);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--pim-ink-2);
  background: var(--pim-tone-gold);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.28);
}

/* Pill chrome, straight from the intro's capability roster. */
.pim-pill {
  display: inline-block;
  margin: 0 0 0.9rem;
  padding: 0.35rem 0.9rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--pim-tone);
  text-shadow: 0 0 10px color-mix(in srgb, var(--pim-tone) 45%, transparent);
  background: color-mix(in srgb, var(--pim-tone) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--pim-tone) 48%, transparent);
  box-shadow:
    0 0 20px color-mix(in srgb, var(--pim-tone) 20%, transparent),
    inset 0 1px 0 color-mix(in srgb, var(--pim-tone) 20%, transparent);
}

/* —— Showcase bands ———————————————————————————————————————————————————
   What replaced the three step tiles on the landing page. A tile with a
   sixty-word paragraph is a paragraph with a border on it: the reader still has
   to read all of it to find out whether it concerns them. A band says the claim
   in three lines and shows it in a picture the width of half the page; all
   three dropped their old paragraph rather than leave a drawer nobody had
   reason to open. The macro still supports one, for a band whose paragraph
   earns the click.

   The copy column is first in source order whichever side the media is on, so
   the sentence reaches a screen reader -- and a phone, where the grid is one
   column -- before the screenshot does. `minmax(0, ...)` on both tracks because
   a grid item defaults to its content width, and a 1440px-wide image would
   otherwise push the band past the shell. */
.pim-bands { display: grid; gap: var(--pim-space-7); }

.pim-showcase {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: var(--pim-space-5);
  align-items: center;
}

/* Alternating is `order` on the copy plus a mirrored ratio: without the second
   line the media track stays the wider of the two only on the bands that happen
   to put it second, and the pictures come out at two different sizes down the
   page. */
.pim-showcase--left { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); }
.pim-showcase--left .pim-showcase-copy { order: 2; }

/* The band an animated diagram gets: copy in a normal measure, picture across
   the whole shell underneath it.

   It is not a stylistic preference. Both diagrams are drawn as a grid of real
   text -- workbook headers, field chips, type verdicts -- with a wire layer
   between two columns, and they drop that wire layer entirely below 760px
   viewport width. Beside a copy column the media track is ~555px, so the picture
   rendered in its phone form, wireless, in the middle of a desktop page, with
   every header wrapped three ways. Across the shell it gets ~1110px, which is
   the size it was drawn for.

   `align-items: start` rather than the inherited `center`: with one column there
   is nothing to centre against, and centring would only add slack above the
   copy. The gap is two steps tighter than a side-by-side band because the
   diagrams carry their own `margin-block` (diagrams.css), and the two intervals
   added up to a hole. */
.pim-showcase--stage {
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
  gap: var(--pim-space-2);
}

/* A paragraph in a stage band still wants a measure -- 1110px of 18px text is
   about 150 characters a line -- but the head row below does not: it is an
   icon, a short heading and three bullets, none of them running prose, and
   capping the row itself would waste the width the diagram needed a stage for
   in the first place. */
.pim-showcase--stage .pim-showcase-copy .pim-lede { max-width: var(--pim-measure); }

/* A grid, not a block: a band's media column may hold a diagram, a screenshot,
   or both, and they stack on the same interval as everything else. */
.pim-showcase-media { display: grid; gap: var(--pim-space-3); }

.pim-showcase-copy .pim-card-glyph { margin-bottom: var(--pim-space-3); }
.pim-showcase-copy .pim-lede { margin-bottom: var(--pim-space-3); }
.pim-showcase-copy .pim-link { color: var(--pim-spark); }

/* The stage bands' head row: icon and step name beside the bullets that used
   to sit stacked underneath them. It exists to buy back vertical room before
   the picture arrives -- three lines under a heading pushed the diagram
   another card-height down the page for no reason a phone couldn't also live
   without, since a phone gets the stacked form anyway once the row wraps.

   The heading block does not grow past ~260px: at three words and an icon it
   never needs to, and letting it grow would just pull the bullets away from
   it. The bullets are the plain stacked list, not the features page's `--row`
   grid -- three items in that grid's two columns came out two-and-one, which
   reads as an accident of wrapping rather than a list, so these three always
   run top to bottom instead. They take what width is left of the row, and
   wrap under the heading with no media query once that space drops below
   their own floor -- the same width a phone hands the heading block, so both
   wrap for the same reason. */
.pim-showcase-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--pim-space-4) var(--pim-space-5);
  margin-bottom: var(--pim-space-3);
}

.pim-showcase-heading { flex: 0 1 260px; }

/* "Step one" reads as a label over an icon and a heading, not a third line the
   same weight as neither -- bigger than the eyebrow anywhere else on the site,
   because here it is doing more work than an eyebrow usually does. */
.pim-showcase--stage > .pim-showcase-copy > .pim-eyebrow { margin-bottom: var(--pim-space-2); font-size: 0.94rem; }

/* Icon and heading on one row instead of stacked: three rows (icon, "step
   one", heading) read as a list of three unrelated things: the icon has
   nothing to sit over once the label above it is doing the counting. */
.pim-showcase-title { display: flex; align-items: center; gap: var(--pim-space-2); }
.pim-showcase-title .pim-card-glyph { margin-bottom: 0; }
.pim-showcase-heading .pim-h2 { margin: 0; }

.pim-showcase-head .pim-points-short { flex: 1 1 380px; }

/* The link used to close the copy column above the picture. A stage band shows
   the picture first now, so the link follows it instead -- the click is
   offered after the reader has seen the thing it explains, not before. The
   drawer that still follows the media for one band needs no override: its own
   `margin-top` already reads right after a picture instead of after prose.

   Kept small on purpose: the diagram already carries its own margin-block
   below it, and the grid gap adds a third interval on top of that -- a full
   `space-3` here stacked all three into 69px, more air than a two-word link
   under a full-width diagram earned. `space-1` still keeps the link visibly a
   separate element rather than pinned to the picture's edge. */
.pim-showcase-link { margin-top: var(--pim-space-1); }

/* —— Short bullets ————————————————————————————————————————————————————
   The visible half of "tuck the detail away": two or three lines that carry the
   claim. Set at body size rather than the smaller description size, because
   these are now the section's primary reading and they are what a skimmer is
   given instead of the prose. */
.pim-points-short {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--pim-space-2);
}

.pim-points-short li {
  display: flex;
  gap: 0.65rem;
  align-items: start;
  font-size: var(--pim-fs-body);
  line-height: 1.6;
  color: var(--pim-text);
}

/* The features page's variant: the two or three claims read across the section
   rather than down it. A stacked list in a 1112px column would be three lines
   each 150 characters long with an ocean to their right, and it would push the
   screenshot -- the thing the section is actually for -- another 150px down the
   page for nothing.

   `auto-fit` with a 260px floor rather than a fixed count because the number of
   bullets is content: three fit across at full width, and at any width where 260
   no longer divides in they fold back to a stack on their own, which is also
   what happens on a phone without a media query having to say so. Not applied to
   the bands' bullets, whose copy column is a measure wide and has no room for a
   second track. */
.pim-points-short--row {
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--pim-space-3) var(--pim-space-4);
}

/* —— Screenshots ——————————————————————————————————————————————————————
   `width: 100%` with `height: auto` against the width/height attributes in the
   markup means the box is reserved at the right shape before the file arrives --
   and keeps that shape if it never does, which is what a reader on a slow
   connection sees.

   The framing is a bezel rather than a border, and that is about what these
   captures actually are. The application has no dark mode -- rxconfig pins
   Reflex and Radix to light and there is no toggle -- so a screenshot of it is a
   white rectangle, and this page is nearly black. At 404px that was a bright
   chip and a 1px hairline was enough to hold it. At full column width it is
   1112px of white, and a hairline around it reads as a stylesheet that failed to
   load rather than as a picture of a program.

   So the image sits inside a dark padded frame: the white is bounded by ink on
   all four sides, which is the whole trick, and the frame carries the radius and
   the drop while the image keeps a small radius of its own because application
   windows have nearly square corners and a heavily rounded screenshot reads as a
   sticker. The inner hairline is black rather than blue -- it has to darken the
   boundary where white meets frame, and a light-blue edge there glows instead.

   What is deliberately absent: any filter on the image. Dimming it or cooling it
   towards the page's palette would make the product look like something it is
   not. The frame changes its surroundings, never its pixels. */
.pim-shot { margin: 0; }

.pim-shot-frame {
  padding: 0.5rem;
  border-radius: calc(var(--pim-radius) + 4px);
  border: 1px solid var(--pim-edge);
  background: linear-gradient(180deg, rgba(30, 58, 112, 0.55), rgba(9, 24, 56, 0.85));
  box-shadow: 0 24px 60px -22px rgba(0, 0, 0, 0.85), inset 0 1px 0 rgba(255, 255, 255, 0.08);
}

.pim-shot img {
  display: block;
  width: 100%;
  max-width: 100%;
  height: auto;
  border-radius: 6px;
  background: var(--pim-surface-flat);
  /* A ring, not a border: a border would be laid outside the radius and show a
     seam at the corners against the frame's gradient. */
  box-shadow: 0 0 0 1px rgba(2, 8, 22, 0.65);
}

.pim-shot figcaption {
  margin-top: var(--pim-space-2);
  color: var(--pim-text-dim);
  font-size: var(--pim-fs-meta);
  line-height: 1.6;
  max-width: var(--pim-measure);
}

/* —— The "under the hood" drawer ———————————————————————————————————————
   `<details>` and nothing else: the site ships no JavaScript, the CSP forbids an
   inline one, and the element is already keyboard-operable and still searchable
   when closed. The summary has to look like a control -- a heading that turns
   out to be clickable is worse than no drawer, because nobody clicks it -- so it
   gets a cursor, a hover wash, a focus ring and a chevron that turns. */
.pim-tech {
  margin-top: var(--pim-space-4);
  border: 1px solid var(--pim-line);
  border-radius: var(--pim-radius);
  background: rgba(9, 24, 56, 0.45);
}

.pim-tech-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--pim-space-3);
  padding: var(--pim-space-2) var(--pim-space-3);
  border-radius: var(--pim-radius);
  cursor: pointer;
  font-family: var(--pim-font-display);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--pim-text-icon);
  /* Both lines are needed: the standard property and the WebKit pseudo-element
     are the two ways a browser draws the default triangle. */
  list-style: none;
}

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

.pim-tech-summary:hover {
  color: var(--pim-text);
  background: rgba(30, 62, 122, 0.45);
}

.pim-tech[open] .pim-tech-summary {
  border-bottom: 1px solid var(--pim-line);
  border-radius: var(--pim-radius) var(--pim-radius) 0 0;
}

.pim-tech-marker {
  display: inline-grid;
  place-items: center;
  width: 1.7rem;
  height: 1.7rem;
  flex: none;
  border-radius: 50%;
  border: 1px solid var(--pim-edge);
  color: var(--pim-spark);
  rotate: 90deg;
  transition: rotate 0.18s ease;
}

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

.pim-tech-body { padding: var(--pim-space-3); }

.pim-tech-body > p {
  color: var(--pim-text-dim);
  font-size: var(--pim-fs-desc);
  line-height: 1.6;
  max-width: var(--pim-measure);
}

.pim-tech-body > p + .pim-deflist { margin-top: var(--pim-space-3); }

/* —— Landing: what it connects ————————————————————————————————————————— */
.pim-ends {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: var(--pim-space-4);
  align-items: center;
}

.pim-end {
  padding: var(--pim-space-4);
  border-radius: var(--pim-radius);
  border: 1px solid var(--pim-line);
  background: var(--pim-surface-flat);
}

.pim-end-heading {
  margin: 0 0 1.2rem;
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pim-text-icon);
}

.pim-endpoints {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 1rem;
}

.pim-endpoints li { display: flex; gap: 0.9rem; align-items: center; }
.pim-endpoints strong { display: block; font-weight: 500; font-size: var(--pim-fs-body); }
.pim-endpoints em {
  display: block;
  font-style: normal;
  font-size: var(--pim-fs-desc);
  line-height: 1.6;
  color: var(--pim-text-dim);
}

.pim-endpoint-glyph {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  flex: none;
  border-radius: 11px;
  color: var(--pim-text-icon);
  background: linear-gradient(160deg, rgba(30, 62, 122, 0.9), rgba(11, 28, 66, 0.9));
  border: 1px solid var(--pim-edge);
}

.pim-end-arrow {
  color: var(--pim-spark);
  filter: drop-shadow(0 0 8px var(--pim-halo));
}

.pim-end-arrow .pim-icon { width: 2rem; height: 2rem; }

/* —— CTA band —————————————————————————————————————————————————————————— */
.pim-cta {
  /* No margin: the section above already ends on a full band of padding, and
     stacking the two opened a dead band the width of the screen. Its own
     padding stays a step below that band, so the CTA reads as attached to the
     page rather than as one more section. */
  padding-block: var(--pim-space-6);
  border-block: 1px solid var(--pim-edge);
  background-color: var(--pim-ink-1);
  background-image: linear-gradient(rgba(76,158,222,.065) 1px, transparent 1px), linear-gradient(90deg, rgba(76,158,222,.065) 1px, transparent 1px), linear-gradient(145deg,#04162b,#071f3d 65%,#0a2b50);
  background-size: 44px 44px, 44px 44px, auto;
}

.pim-cta-inner {
  display: flex;
  flex-wrap: wrap;
  gap: 2rem;
  align-items: center;
  justify-content: space-between;
}

.pim-cta .pim-actions { margin-top: 0; }

.pim-cta .pim-h2,
.pim-bring > .pim-shell > .pim-heading .pim-h2 {
  color: #f7f9fc;
}

.pim-cta .pim-lede,
.pim-bring > .pim-shell > .pim-heading .pim-lede,
.pim-bring-action .pim-note,
.pim-bring-privacy {
  color: #b9c9dc;
}

.pim-cta .pim-btn--ghost,
.pim-bring .pim-btn--ghost {
  color: #f7f9fc;
  border-color: rgba(185, 201, 220, 0.55);
}

/* —— Bring us a file ——————————————————————————————————————————————————
   The band that asks for a workbook. It borrows the CTA band's lit treatment
   rather than `.pim-section--alt`, because on the landing page it is what closes
   the page — where a wash and two hairlines would read as one more section — and
   on the consult page it has to separate itself from the contact block directly
   below it. Full section padding, though, unlike the CTA band: this one has a
   heading, three cards and two notes in it, not one line and two buttons. */
.pim-bring {
  padding-block: var(--pim-space-7);
  border-block: 1px solid var(--pim-edge);
  background-color: var(--pim-ink-1);
  background-image: linear-gradient(rgba(76,158,222,.065) 1px, transparent 1px), linear-gradient(90deg, rgba(76,158,222,.065) 1px, transparent 1px), linear-gradient(145deg,#04162b,#071f3d 65%,#0a2b50);
  background-size: 44px 44px, 44px 44px, auto;
}

/* The button and the "there is nothing to upload here" line on one row, so the
   sentence is read at the moment the eye is looking for a file picker. It wraps
   to two rows before the note gets squeezed: `flex-wrap` plus a measure on the
   note, which is narrower than the prose default because it sits beside
   something. */
.pim-bring-action {
  margin-top: var(--pim-space-5);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--pim-space-3);
}

.pim-bring-action .pim-note { margin: 0; max-width: 46ch; }

.pim-bring-privacy { margin-top: var(--pim-space-3); }

/* —— Features page ————————————————————————————————————————————————————— */
/* The features page used to put a 220px anchor sidebar beside its sections. It
   does not any more, at any width, and the reason is arithmetic: the sidebar and
   its gap took 262px out of a 1112px shell, the sections column was left with
   850px, the two-column body inside it halved that again, and every screenshot
   of a 1440px application page came out 404px wide -- a scale of 0.28, at which a
   table header is under three pixels tall and a ten-column product list conveys
   only that a screen exists.

   The row is what the narrow layout already did, so this is one treatment
   instead of two, and it keeps both of the things the sidebar was for: the eight
   labels are all visible at once, and it stays put while you scroll. */
.pim-withnav {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--pim-space-4);
}

/* A grid item defaults to min-width:auto, which is its content width. Without
   this the anchor rail's overflow-x row refuses to shrink and drags the whole
   page sideways on a phone -- the scrollbar appears on <html>, not on the rail. */
.pim-withnav > * { min-width: 0; }

/* Sticky under the header rather than at the top of the viewport: the header is
   68px and z-index 10, so a row that stopped at 0 would slide under it and be
   half hidden. 1px of overlap rather than a flush 68 so a subpixel scroll
   position cannot open a hairline of page between the two bars.

   The negative inline margin plus matching padding is what lets the row's
   background reach the shell's padding: without it the chips scroll under a 24px
   strip of bare page on each side and the section content shows through beside
   them. */
.pim-anchors {
  position: sticky;
  top: 67px;
  z-index: 5;
  display: flex;
  align-items: center;
  /* The label that used to sit here is gone, so the row's only child is the
     chip list, and a flex child shrinks to its own content width by default --
     left in place, that left the chips flush to the left edge with whatever
     was left of the row's width empty on the right. Centering the row is what
     centering the rail actually is, now that there is nothing else in it. */
  justify-content: center;
  gap: var(--pim-space-2);
  margin-inline: calc(-1 * var(--pim-space-3));
  padding: var(--pim-space-2) var(--pim-space-3);
  border-bottom: 1px solid var(--pim-line);
  background: color-mix(in srgb, var(--pim-ink-2) 88%, transparent);
  backdrop-filter: blur(10px);
}

/* Wraps instead of scrolling: a chip a reader cannot see because it is off the
   edge of a horizontal strip is a chip that does not exist to them, and eight
   sections is short enough that a second (rarely third) row costs less than a
   hidden one costs. `min-width: 0` on the flex child above is what still lets
   the row itself shrink to the shell instead of overflowing it sideways --
   that constraint did not go away, only what happens at the limit did. */
.pim-anchors ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  /* Centers each wrapped row on its own, not only the block as a whole -- a
     shorter second row (fewer chips than the first) would otherwise sit at
     the left edge of an already-centred block, which is centred in name only
     once there is more than one row. */
  justify-content: center;
  gap: 0.4rem;
  min-width: 0;
}

/* `inline-flex` rather than `block` since a chip is now an icon and a word:
   the two need to sit on one baseline instead of however an inline SVG and a
   text node happen to fall in normal flow. */
.pim-anchors a {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.34rem 0.75rem;
  border: 1px solid var(--pim-line);
  border-radius: 999px;
  font-size: 0.82rem;
  letter-spacing: 0.05em;
  text-decoration: none;
  white-space: nowrap;
  color: var(--pim-text-dim);
}

.pim-anchors a .pim-icon { flex: none; }

.pim-anchors a:hover {
  color: var(--pim-tone);
  border-color: var(--pim-tone);
  background: color-mix(in srgb, var(--pim-tone) 8%, transparent);
}

.pim-sections { display: grid; gap: var(--pim-space-6); }

/* Clears the site header (68px) and the sticky chip row beneath it, so a chip
   does not land its own target underneath itself. The chip row wraps now
   instead of scrolling (see .pim-anchors ul), so its height is not one
   constant -- measured in a real browser across the whole sticky range
   (641px, where it stops being sticky, up to a wide desktop): one row at
   1100px and up (70px), two rows below that (116px), never three. This uses
   the two-row height at every width rather than matching the exact,
   non-breakpoint-aligned point where the row itself wraps -- the cost of
   that at the wide end is a section landing with a little more clearance
   than it strictly needs, not the header a click on a chip used to bury
   under the bar at the narrow end. */
.pim-feature { scroll-margin-top: 208px; }

.pim-feature-head {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1.2rem;
  align-items: start;
  margin-bottom: var(--pim-space-4);
  padding-bottom: var(--pim-space-3);
  border-bottom: 1px solid var(--pim-line);
}

.pim-feature-head .pim-card-glyph { margin-bottom: 0; }

/* Bullets above the screenshot, not beside it. Beside it was what cost every
   capture three quarters of its width; see .pim-withnav. A single column here,
   with the row of claims deciding its own internal columns. */
.pim-feature-body {
  display: grid;
  gap: var(--pim-space-4);
}

.pim-deflist {
  margin: 0;
  display: grid;
  gap: var(--pim-space-3);
}

.pim-deflist--two { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }

/* Same reasoning as the bullets row, one level down: a features drawer holds the
   five prose rows that used to be the visible section, and opened in a 1112px
   column a single stack of them is five 150-character measures. Two-up, by the
   same auto-fit rule, so it is still one column on a phone. */
.pim-feature .pim-deflist { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }

.pim-def {
  padding-left: 1.1rem;
  border-left: 2px solid color-mix(in srgb, var(--pim-tone) 45%, transparent);
}

.pim-def dt {
  font-size: var(--pim-fs-body);
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--pim-text);
}

.pim-def dd {
  margin: 0.3rem 0 0;
  color: var(--pim-text-dim);
  font-size: var(--pim-fs-desc);
  line-height: 1.6;
}

/* —— Agent page ———————————————————————————————————————————————————————— */
.pim-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--pim-space-5);
  align-items: start;
}

.pim-points {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--pim-space-4);
}

.pim-points li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1rem;
  align-items: start;
}

.pim-points p {
  color: var(--pim-text-dim);
  font-size: var(--pim-fs-desc);
  line-height: 1.6;
}

.pim-point-glyph {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 12px;
  color: var(--pim-spark);
  background: rgba(11, 28, 66, 0.9);
  border: 1px solid var(--pim-edge);
  box-shadow: 0 0 18px rgba(20, 60, 140, 0.5);
}

/* —— Case study page ———————————————————————————————————————————————————
   Eight blocks that exist only here, one per `kind` in
   templates/_partials/case.html.j2. The page's frame -- the shell, the sticky
   chip rail, the section cards and the drawer -- is the features page's,
   reused unchanged; everything below is the evidence that sits inside it.

   No animation anywhere in this block. The one moving thing on the page is the
   combinatorial ladder, which is diagrams.css's, and the argument the other
   seven blocks make is a static one: a code decomposed, four paths side by
   side, three renderings of one record. Motion would only be decoration.

   Monospace appears four times -- the ordering codes, the rule expressions, the
   SKU segments and the part numbers -- and always for the same reason it appears
   in the mapping diagram: these are literal catalog content, not writing, and a
   proportional face invites a reader to skim "AU-T-14-30" as a word. */

/* The reader's own monospace face, as everywhere else on this site: nothing is
   fetched for it, so the page keeps making no external request. Declared on the
   page's own body class -- base.html.j2 stamps pim-page--<page_id> -- so it is
   in scope for every block below and for nothing else. */
.pim-page--cases {
  --pim-case-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* The step number, inside the heading rather than above it: the eight are a
   sequence, and a reader who lands on #sku from the rail should see that they
   arrived at five of eight. Tabular so 01 and 08 are the same width. */
.pim-case-step {
  font-family: var(--pim-font-display);
  font-variant-numeric: tabular-nums;
  color: var(--pim-tone);
  opacity: 0.65;
}

.pim-case-beat .pim-feature-body > .pim-lede { max-width: var(--pim-measure); }

/* —— 02  Option records ——
   The ordering code at display size, an arrow, and what it decomposes into. */
.pim-optrecs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--pim-space-4);
  width: 100%;
}

.pim-optrecs--single { grid-template-columns: minmax(0, min(100%, 30rem)); }

.pim-optrec {
  padding: var(--pim-space-4);
  border: 1px solid var(--pim-edge);
  border-top: 2px solid var(--pim-tone);
  border-radius: var(--pim-radius);
  background: var(--pim-surface);
}

/* Wraps, so a long caption drops to its own full-width line under the code
   chip rather than being squeezed into the ~120px left beside it. */
.pim-optrec-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--pim-space-2);
  padding-bottom: var(--pim-space-3);
  margin-bottom: var(--pim-space-3);
  border-bottom: 1px solid var(--pim-line);
}

.pim-optrec-code {
  flex: none;
  min-width: 2.4rem;
  padding: 0.15rem 0.55rem;
  border-radius: 8px;
  background: color-mix(in srgb, var(--pim-tone) 18%, transparent);
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-size: 1.35rem;
  font-weight: 600;
  text-align: center;
  color: var(--pim-tone);
}

.pim-optrec-arrow { flex: none; color: var(--pim-text-dim); }

/* min-width so it can shrink at all: a flex item defaults to its content width,
   and "Control-system power supply" set uppercase beside a fixed-width code
   chip was 18px wider than the card, which put a scrollbar on the whole page.

   `break-word`, not `anywhere`. They look interchangeable and are not:
   `anywhere` counts break opportunities toward the intrinsic min-content size,
   so flex stopped wrapping the caption to its own line and started breaking it
   mid-word instead -- "CONT ROL- SYST EM POWE R SUPP LY". `break-word` leaves
   min-content alone and only breaks a word that cannot fit on a line of its
   own, which is the last resort it is supposed to be. */
.pim-optrec-dim {
  min-width: 0;
  overflow-wrap: break-word;
  font-size: var(--pim-fs-meta);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pim-text-dim);
}

/* Label left, value right, on one line each. A definition list rather than a
   table because that is what it is -- and it stays a list for a screen reader
   even though it is drawn as two columns. */
.pim-optrec-rows { margin: 0; display: grid; gap: 0.45rem; }

.pim-optrec-rows > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--pim-space-3);
}

.pim-optrec-rows dt {
  font-size: 0.86rem;
  color: var(--pim-text-dim);
}

.pim-optrec-rows dd {
  margin: 0;
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-size: 0.9rem;
  color: var(--pim-text);
  text-align: right;
}

.pim-optrec-relation {
  margin: var(--pim-space-3) 0 0;
  padding-top: var(--pim-space-3);
  border-top: 1px solid var(--pim-line);
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  color: var(--pim-tone);
}

/* —— 03  Levels ——
   Stacked, not columns: the claim is descent, and three columns would read as
   three alternatives. The connector between them is drawn on the list rather
   than on each item so the last one has nothing hanging off it. */
.pim-tiers {
  display: grid;
  gap: var(--pim-space-3);
  margin: 0;
  padding: 0;
  list-style: none;
  width: 100%;
  counter-reset: tier;
}

.pim-tier {
  position: relative;
  padding: var(--pim-space-4);
  border: 1px solid var(--pim-edge);
  border-left: 3px solid var(--pim-tone);
  border-radius: var(--pim-radius);
  background: var(--pim-surface);
}

/* The inheritance arrow, in the gap under every tier but the last. */
.pim-tier:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 2rem;
  bottom: calc(var(--pim-space-3) * -1);
  width: 1px;
  height: var(--pim-space-3);
  background: linear-gradient(var(--pim-tone), transparent);
}

.pim-tier-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--pim-space-2);
  margin-bottom: var(--pim-space-3);
}

.pim-tier-name {
  font-family: var(--pim-font-display);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--pim-tone);
}

.pim-tier-sub {
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-size: 0.88rem;
  color: var(--pim-text-dim);
}

.pim-tier-items {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0 0 var(--pim-space-3);
  padding: 0;
  list-style: none;
}

.pim-tier-items li {
  padding: 0.18rem 0.6rem;
  border: 1px solid var(--pim-edge);
  border-radius: 999px;
  background: var(--pim-surface-flat);
  font-size: 0.82rem;
  color: var(--pim-text);
}

.pim-tier-note {
  margin: 0;
  font-size: var(--pim-fs-meta);
  color: var(--pim-text-dim);
}

/* —— 04  Rules ——
   The dependencies as prose and the same knowledge as the setup stores it,
   side by side. Two columns where there is room, because seeing both at once
   is the argument. */
.pim-rulesets {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--pim-space-5);
  width: 100%;
}

.pim-ruleset .pim-h3 { margin: 0 0 var(--pim-space-3); }
.pim-ruleset .pim-points-short { margin: 0; }

.pim-rules {
  display: grid;
  gap: var(--pim-space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.pim-rule {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  padding: var(--pim-space-3);
  border: 1px solid var(--pim-edge);
  border-radius: var(--pim-radius);
  background: var(--pim-surface-flat);
}

.pim-rule-kw {
  font-family: var(--pim-font-display);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--pim-tone-rose);
}

.pim-rule-kw--then { color: var(--pim-tone-mint); }
.pim-rule-kw--and { color: var(--pim-text-dim); }

/* The stacked form, for a rule whose conditions or consequences are a set. Two
   halves side by side where there is room, so the reader sees a combination
   producing a combination -- which is the claim -- rather than a long line. */
.pim-rule--multi {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
  align-items: start;
  gap: var(--pim-space-3) var(--pim-space-4);
}

.pim-rule-half {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline;
  gap: var(--pim-space-2);
  min-width: 0;
}

.pim-rule-list {
  display: grid;
  gap: 0.3rem;
  margin: 0;
  padding: 0;
  list-style: none;
  min-width: 0;
}

/* AND sits before its condition rather than between the rows, so the operator
   belongs to the line it qualifies and a wrapped condition cannot separate
   them. */
.pim-rule-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem;
  min-width: 0;
}

.pim-rule-expr {
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-size: 0.86rem;
  color: var(--pim-text);
  background: none;
  padding: 0;
}

/* —— 05  The generated SKU ——
   Segments as columns: the token as it appears in the code, the decision it
   came from underneath it. Scrolls inside itself rather than wrapping, because
   an ordering code broken across two lines stops being one code. */
.pim-sku {
  width: 100%;
  margin: 0;
}

.pim-sku-code {
  display: flex;
  align-items: flex-end;
  gap: 0.15rem;
  overflow-x: auto;
  padding: var(--pim-space-4) var(--pim-space-3);
  border: 1px solid var(--pim-edge);
  border-radius: var(--pim-radius);
  background:
    radial-gradient(90% 140% at 50% 0%, var(--pim-glow-core), transparent 70%),
    var(--pim-surface-flat);
}

.pim-sku-seg {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  flex: none;
  padding: 0 0.3rem;
}

.pim-sku-token {
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-size: clamp(1.3rem, 3.4vw, 2rem);
  font-weight: 600;
  line-height: 1;
  color: var(--pim-tone);
  text-shadow: 0 0 18px color-mix(in srgb, var(--pim-tone) 35%, transparent);
}

/* The dimension the token came from, under a hairline in the token's own tone
   -- so the pairing is read as a bracket rather than as a caption. */
.pim-sku-label {
  padding-top: 0.35rem;
  border-top: 2px solid color-mix(in srgb, var(--pim-tone) 55%, transparent);
  font-size: 0.68rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--pim-text-dim);
}

/* A real hyphen in the flow, so selecting the code copies the code. It sits on
   the token's baseline, not the label's. */
.pim-sku-dash {
  flex: none;
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-size: clamp(1.3rem, 3.4vw, 2rem);
  line-height: 1;
  color: var(--pim-text-dim);
  /* Aligned with the tokens above the labels, which are 0.35rem + the label's
     own line box below the row's baseline. */
  margin-bottom: 1.55rem;
}

.pim-sku figcaption {
  margin-top: var(--pim-space-3);
  max-width: var(--pim-measure);
  font-size: var(--pim-fs-meta);
  color: var(--pim-text-dim);
}

/* —— 06  Relationships ——
   The configuration, then one row per edge. The verb is a column of its own so
   the four read as sentences about the same subject rather than as four cards. */
.pim-graph { width: 100%; }

.pim-graph-hub {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding: var(--pim-space-4);
  border: 1px solid var(--pim-edge);
  border-radius: var(--pim-radius);
  background: var(--pim-surface);
}

.pim-graph-kind {
  font-size: var(--pim-fs-meta);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pim-text-dim);
}

.pim-graph-title {
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-size: 1.05rem;
  color: var(--pim-text);
}

.pim-graph-edges {
  display: grid;
  gap: var(--pim-space-2);
  margin: var(--pim-space-3) 0 0;
  padding: 0 0 0 var(--pim-space-5);
  list-style: none;
  /* The spine every edge hangs off, drawn on the list so it starts under the
     hub and stops at the last edge. */
  border-left: 1px solid var(--pim-line);
}

.pim-graph-edge {
  display: grid;
  grid-template-columns: minmax(7rem, 10rem) minmax(0, 1fr);
  align-items: center;
  gap: var(--pim-space-3);
  position: relative;
}

.pim-graph-edge::before {
  content: "";
  position: absolute;
  left: calc(var(--pim-space-5) * -1);
  width: var(--pim-space-4);
  height: 1px;
  background: color-mix(in srgb, var(--pim-tone) 55%, transparent);
}

.pim-graph-verb {
  font-size: 0.82rem;
  font-style: italic;
  color: var(--pim-text-dim);
}

.pim-graph-node {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--pim-space-2);
  padding: var(--pim-space-2) var(--pim-space-3);
  border: 1px solid color-mix(in srgb, var(--pim-tone) 34%, transparent);
  border-radius: var(--pim-radius);
  background: var(--pim-surface-flat);
}

.pim-graph-glyph { display: flex; flex: none; color: var(--pim-tone); }
.pim-graph-glyph .pim-icon { width: 1.05rem; height: 1.05rem; }

.pim-graph-target {
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-size: 0.9rem;
  color: var(--pim-text);
}

.pim-graph-targets {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  min-width: 0;
}

/* Inside a set they are chips; alone, the target is just the node's own text.
   Same class either way, because it is the same thing being named. */
.pim-graph-targets .pim-graph-target {
  padding: 0.08rem 0.45rem;
  border: 1px solid color-mix(in srgb, var(--pim-tone) 30%, transparent);
  border-radius: 999px;
  font-size: 0.82rem;
}

.pim-graph-note {
  margin-left: auto;
  font-size: var(--pim-fs-meta);
  color: var(--pim-text-dim);
}

.pim-graph-reverse-heading { margin: var(--pim-space-5) 0 var(--pim-space-3); }

.pim-graph-reverse {
  width: 100%;
  max-width: 34rem;
  padding: var(--pim-space-4);
  border: 1px solid var(--pim-edge);
  border-top: 2px solid var(--pim-tone);
  border-radius: var(--pim-radius);
  background: var(--pim-surface);
}

.pim-graph-reverse header {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding-bottom: var(--pim-space-3);
  margin-bottom: var(--pim-space-3);
  border-bottom: 1px solid var(--pim-line);
}

/* —— 07  Classifications ——
   Four breadcrumbs of the same product. Each scrolls inside its own row rather
   than wrapping, so a long path never pushes the page sideways. */
.pim-paths {
  display: grid;
  gap: var(--pim-space-2);
  margin: 0;
  padding: 0;
  list-style: none;
  width: 100%;
}

.pim-path {
  display: grid;
  grid-template-columns: minmax(8rem, 11rem) minmax(0, 1fr);
  align-items: center;
  gap: var(--pim-space-3);
  padding: var(--pim-space-3);
  border: 1px solid var(--pim-edge);
  border-left: 3px solid var(--pim-tone);
  border-radius: var(--pim-radius);
  background: var(--pim-surface-flat);
}

.pim-path-source {
  font-size: var(--pim-fs-meta);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pim-tone);
}

.pim-path-crumbs {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  min-width: 0;
  overflow-x: auto;
}

.pim-path-crumb {
  white-space: nowrap;
  font-size: 0.9rem;
  color: var(--pim-text);
}

.pim-path-crumbs .pim-path-crumb:last-child { color: var(--pim-spark); }

.pim-path-sep {
  display: flex;
  flex: none;
  color: var(--pim-text-dim);
  opacity: 0.6;
}

/* —— 08  Three renderings ——
   Drawn identically on purpose: the whole claim is that only the representation
   differs, so anything that made one card look like a different kind of object
   would argue the opposite. */
.pim-renders {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: var(--pim-space-4);
  width: 100%;
}

.pim-render {
  display: flex;
  flex-direction: column;
  gap: var(--pim-space-3);
  padding: var(--pim-space-4);
  border: 1px solid var(--pim-edge);
  border-top: 2px solid var(--pim-tone);
  border-radius: var(--pim-radius);
  background: var(--pim-surface);
}

.pim-render-head {
  display: flex;
  align-items: center;
  gap: var(--pim-space-3);
}

.pim-render-head .pim-card-glyph { flex: none; margin-bottom: 0; }
.pim-render-head .pim-h3 { margin: 0; }

.pim-render-lines {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.3rem;
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-size: 0.85rem;
  color: var(--pim-text);
}

.pim-render-body {
  margin: 0;
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-size: 0.88rem;
  line-height: 1.65;
  color: var(--pim-text);
}

/* —— The index: one card per vertical ————————————————————————————————— */

/* Two up, which is 2x2 for the four verticals rather than 3+1. 24rem is chosen
   to land on two columns in the 1112px shell: at three, the label above each
   heading ("Industrial automation / Pneumatics") breaks onto three lines and
   the cards stop reading as four peers. */
.pim-studies {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr));
  gap: var(--pim-space-4);
}

.pim-study {
  display: flex;
  flex-direction: column;
  gap: var(--pim-space-3);
  padding: var(--pim-space-5);
  border: 1px solid var(--pim-edge);
  border-top: 2px solid var(--pim-tone);
  border-radius: var(--pim-radius);
  background: var(--pim-surface);
}

/* An announced vertical is the same size card as a written one -- four
   verticals is a real statement about scope and shrinking two of them into a
   footnote would make it read as "one and a half". What separates them is the
   action, or its absence, not the weight: no top edge in the tone, and the
   surface goes flat. */
.pim-study--planned {
  border-top-color: var(--pim-edge);
  border-style: dashed;
  background: var(--pim-surface-flat);
}

.pim-study-head {
  display: flex;
  align-items: flex-start;
  gap: var(--pim-space-3);
}

.pim-study-head .pim-card-glyph { flex: none; margin-bottom: 0; }
.pim-study-head .pim-eyebrow { margin-bottom: 0.3rem; }
.pim-study-head .pim-h3 { margin: 0; }

.pim-study-headline {
  margin: 0;
  font-family: var(--pim-font-display);
  font-size: 1.02rem;
  line-height: 1.4;
  color: var(--pim-spark);
}

.pim-study-summary {
  margin: 0;
  font-size: 0.92rem;
  color: var(--pim-text-dim);
}

/* Pinned to the bottom, so a row of cards with summaries of different lengths
   still has its four links on one line. */
.pim-study-link { margin-top: auto; }

/* The line under a block that says what the picture was for. */
.pim-beat-note { max-width: var(--pim-measure); }

/* —— Configuration spec sheet ——
   Deliberately plain: this block's job is to be the small boring list that the
   two blocks after it turn out to be doing all the work behind, so anything
   decorative here would argue against the point. */
.pim-specs {
  width: 100%;
  max-width: 40rem;
  padding: var(--pim-space-4);
  border: 1px solid var(--pim-edge);
  border-radius: var(--pim-radius);
  background: var(--pim-surface);
}

.pim-specs .pim-h3 { margin: 0 0 var(--pim-space-3); }

.pim-specs-rows { margin: 0; display: grid; }

.pim-specs-rows > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--pim-space-4);
  padding: 0.55rem 0;
  border-top: 1px solid var(--pim-line);
}

.pim-specs-rows > div:first-child { border-top: 0; }

/* The two decisions the next two sections are about. A left rule in the tone
   rather than a bolder weight: the row is not more important to read, it is
   the one being pointed at. */
.pim-specs-row--lead {
  margin-left: calc(var(--pim-space-3) * -1);
  padding-left: calc(var(--pim-space-3) - 3px);
  border-left: 3px solid var(--pim-tone);
}

.pim-specs-rows dt { color: var(--pim-text-dim); font-size: 0.9rem; }

.pim-specs-rows dd {
  margin: 0;
  text-align: right;
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-size: 0.92rem;
  color: var(--pim-text);
}

/* —— Calculated dimensions ——
   The variable, then one row per dependent dimension written as the arithmetic
   it actually is. Four columns: the drawing reference, the base dimension, the
   operator carrying the stroke, and the resolved value. Showing the sum rather
   than only the answer is the entire block; a table of resolved numbers would
   look exactly like the stored table this replaces. */
.pim-formula {
  width: 100%;
  max-width: 40rem;
  padding: var(--pim-space-4);
  border: 1px solid var(--pim-edge);
  border-radius: var(--pim-radius);
  background:
    radial-gradient(90% 130% at 50% 0%, var(--pim-glow-core), transparent 70%),
    var(--pim-surface-flat);
}

.pim-formula-var {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--pim-space-4);
  padding-bottom: var(--pim-space-3);
  margin-bottom: var(--pim-space-3);
  border-bottom: 1px solid var(--pim-edge);
}

.pim-formula-var-label {
  font-size: var(--pim-fs-meta);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pim-text-dim);
}

.pim-formula-var-value {
  font-family: var(--pim-font-display);
  font-variant-numeric: tabular-nums;
  font-size: 1.7rem;
  font-weight: 700;
  line-height: 1;
  color: var(--pim-tone);
}

.pim-formula-var-value small {
  margin-left: 0.25rem;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--pim-text-dim);
}

.pim-formula-rows {
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  align-items: baseline;
  gap: 0.55rem var(--pim-space-3);
}

.pim-formula-head {
  font-size: var(--pim-fs-meta);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pim-text-dim);
}

.pim-formula-head--result { text-align: right; }

/* The drawing reference. A letter, so it needs to read as a label and not as an
   algebraic variable somebody could solve for. */
.pim-formula-ref {
  min-width: 1.6rem;
  padding: 0.05rem 0.4rem;
  border-radius: 5px;
  background: color-mix(in srgb, var(--pim-tone) 16%, transparent);
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-size: 0.85rem;
  font-weight: 600;
  text-align: center;
  color: var(--pim-tone);
}

.pim-formula-base,
.pim-formula-op,
.pim-formula-result {
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-variant-numeric: tabular-nums;
  font-size: 0.95rem;
}

.pim-formula-base { color: var(--pim-text-dim); }
.pim-formula-op { color: var(--pim-text-dim); opacity: 0.8; }

.pim-formula-result {
  text-align: right;
  font-weight: 600;
  color: var(--pim-spark);
}

.pim-formula-result small {
  margin-left: 0.2rem;
  font-weight: 400;
  color: var(--pim-text-dim);
}

/* —— The bus-current budget ————————————————————————————————————————————
   A ledger: one row per consumer, a rule, the sum, a meter, what it is measured
   against, and a verdict. Every figure under the rule is computed in the
   template from the rows -- see beat_budget -- so nothing here can disagree
   with the list above it.

   Tabular figures throughout and a fixed-width figure column, because the whole
   block is an addition and a column of numbers that do not line up is an
   addition a reader cannot check. */
.pim-budget {
  width: 100%;
  max-width: 40rem;
  padding: var(--pim-space-4);
  border: 1px solid var(--pim-edge);
  border-radius: var(--pim-radius);
  background:
    radial-gradient(90% 130% at 50% 0%, var(--pim-glow-core), transparent 70%),
    var(--pim-surface-flat);
}

.pim-budget-rows {
  display: grid;
  gap: 0.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.pim-budget-rows li {
  display: grid;
  grid-template-columns: minmax(6rem, auto) minmax(0, 1fr) 5.5rem;
  align-items: baseline;
  gap: var(--pim-space-3);
}

.pim-budget-code {
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-size: 0.88rem;
  color: var(--pim-text);
}

.pim-budget-role {
  font-size: 0.86rem;
  color: var(--pim-text-dim);
}

.pim-budget-ma {
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-variant-numeric: tabular-nums;
  font-size: 0.88rem;
  text-align: right;
  color: var(--pim-text-dim);
}

/* The rule under the addition. On the sum rather than as a separate element,
   so it cannot end up on the wrong side of a margin. */
.pim-budget-sum {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--pim-space-3);
  margin: var(--pim-space-3) 0 0;
  padding-top: var(--pim-space-3);
  border-top: 1px solid var(--pim-edge);
  font-size: 0.9rem;
  color: var(--pim-text-dim);
}

.pim-budget-total {
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-variant-numeric: tabular-nums;
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--pim-spark);
}

/* Decoration for the three figures around it, which is why it is aria-hidden in
   the markup: it adds a glance, not a fact. */
.pim-budget-meter {
  height: 7px;
  margin: var(--pim-space-3) 0;
  border-radius: 999px;
  background: color-mix(in srgb, var(--pim-text-dim) 22%, transparent);
  overflow: hidden;
}

.pim-budget-meter > span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--pim-tone) 70%, transparent),
    var(--pim-spark));
}

.pim-budget--over .pim-budget-meter > span {
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--pim-tone-peach) 70%, transparent),
    var(--pim-tone-rose));
}

.pim-budget--over .pim-budget-total { color: var(--pim-tone-rose); }

.pim-budget-against {
  display: grid;
  gap: 0.35rem;
  margin: 0;
}

.pim-budget-against > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--pim-space-3);
}

.pim-budget-against dt { font-size: 0.86rem; color: var(--pim-text-dim); }

.pim-budget-against dd {
  margin: 0;
  font-family: var(--pim-case-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-variant-numeric: tabular-nums;
  font-size: 0.9rem;
  color: var(--pim-text);
}

.pim-budget-verdict {
  display: flex;
  align-items: center;
  gap: var(--pim-space-2);
  margin: var(--pim-space-3) 0 0;
  padding-top: var(--pim-space-3);
  border-top: 1px solid var(--pim-line);
  font-size: 0.92rem;
  color: var(--pim-tone-mint);
}

.pim-budget-verdict .pim-icon { flex: none; }

.pim-budget--over .pim-budget-verdict { color: var(--pim-tone-rose); }

/* —— Pricing page —————————————————————————————————————————————————————— */

/* #engagements is the Pricing page's plan-grid section (unique id, this page
   only). Cuts the dead space above the cards so the grid starts closer to
   the viewport top on a typical laptop screen. */
#engagements { padding-top: 2.5rem; }

.pim-plan {
  display: flex;
  flex-direction: column;
  padding: var(--pim-space-3);
  border-radius: var(--pim-radius);
  border: 1px solid var(--pim-edge);
  background: var(--pim-surface);
}

.pim-plan--featured {
  border-color: color-mix(in srgb, var(--pim-tone) 60%, transparent);
  box-shadow: 0 0 40px color-mix(in srgb, var(--pim-tone) 18%, transparent);
}

/* The card is a column flexbox, which would stretch the pill to its full width
   and turn a chip into a banner. */
.pim-plan .pim-pill { align-self: flex-start; }

.pim-plan-summary {
  color: var(--pim-text-dim);
  font-size: var(--pim-fs-desc);
  line-height: 1.6;
}

.pim-plan-price {
  margin: var(--pim-space-2) 0 0.8rem;
  font-family: var(--pim-font-display);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pim-text-icon);
}

.pim-plan .pim-btn { align-self: flex-start; }

/* The footnote a row's own `*` points to. Small and dim like `.pim-note`
   elsewhere, because it is a qualifier on the plan, not a feature of it. */
.pim-plan-note {
  margin: var(--pim-space-2) 0 0;
  color: var(--pim-text-dim);
  font-size: var(--pim-fs-meta);
  line-height: 1.6;
}

/* The same gold the "In Beta" ribbon uses (see .pim-card-ribbon), so "Beta"
   reads as one concept whether it is a corner strip on the Agent page or a
   word in a footnote here. */
.pim-plan-note-term { color: var(--pim-tone-gold); font-weight: 600; }

.pim-ticks {
  margin: var(--pim-space-3) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.65rem;
  /* Pushes the price and the button to the bottom of a plan card, so three
     cards with different list lengths still line up. */
  flex: 1;
}

.pim-ticks li {
  display: flex;
  gap: 0.65rem;
  align-items: start;
  color: var(--pim-text-dim);
  font-size: var(--pim-fs-desc);
  line-height: 1.6;
}

/* Pricing-only tightening of the shared .pim-ticks list. .pim-ticks itself
   is also used by the Consult page's contact checklist, so these overrides
   are scoped under .pim-plan rather than touching the shared rules above. */
.pim-plan .pim-ticks { margin-top: var(--pim-space-2); gap: 0.45rem; }
.pim-plan .pim-ticks li { font-size: var(--pim-fs-meta); line-height: 1.5; }
.pim-plan-limits { margin-top: 1.15rem; padding-top: .9rem; border-top: 1px solid var(--pim-line); }
.pim-plan-limits-label { margin: 0 0 .45rem; color: var(--pim-text); font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; }
.pim-plan-limits ul { margin: 0; padding: 0; list-style: none; display: grid; gap: .25rem; }
.pim-plan-limits li { color: var(--pim-text-dim); font-size: .78rem; line-height: 1.45; }

.pim-contact {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: var(--pim-space-5);
  align-items: start;
  padding: var(--pim-space-5);
  border-radius: var(--pim-radius);
  border: 1px solid var(--pim-edge);
  background:
    radial-gradient(ellipse 70% 120% at 0% 0%, rgba(56, 132, 255, 0.16), transparent 70%),
    var(--pim-surface-flat);
}

.pim-contact-main .pim-btn { margin-top: var(--pim-space-4); }
.pim-contact-side .pim-h3 { margin-top: var(--pim-space-4); }
.pim-contact-side .pim-h3:first-child { margin-top: 0; }

.pim-numbered {
  margin: 0.8rem 0 0;
  padding-left: 1.2rem;
  display: grid;
  gap: 0.5rem;
  color: var(--pim-text-dim);
  font-size: var(--pim-fs-desc);
  line-height: 1.6;
}

.pim-numbered::marker { color: var(--pim-tone); }

/* —— Replay console —————————————————————————————————————————————————————
   The Agent page's eight capabilities: a rail of names on the left, one
   replayed agent run on the right. The chrome copies the application's own
   panel (assets/agent_chrome.css) -- user bubble on the right, assistant block
   full width beneath it, monospace tool trace, run meta -- because the point of
   the section is that this is what the product looks like working, and an
   invented chat skin would be a picture of a different thing.

   Switching is a radio group plus `:has()`. The per-run rules that pair tab N
   with panel N are generated in the page template's `head` block, so adding a
   ninth capability to the locale file cannot leave a ninth panel that never
   shows. Everything that is not that index plumbing is here. */
.pim-console {
  display: grid;
  grid-template-columns: minmax(232px, 296px) 1fr;
  gap: var(--pim-space-4);
  align-items: start;
  margin-top: var(--pim-space-5);
  /* Where `scrollIntoView` stops when the reader picks a job
     (static/js/agent-console.js): the 68px sticky header plus a little air. The
     script does not know this number and should not -- it is a styling fact. */
  scroll-margin-top: 76px;
}

/* Sticky so a long run can be read with the other seven still in reach. The
   offset clears the sticky header. */
.pim-console-rail {
  display: grid;
  gap: 0.5rem;
  position: sticky;
  top: 88px;
}

.pim-console-tab {
  position: relative;
  display: grid;
  /* Glyph, the name-and-chip cell, the cue arrow. */
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.7rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--pim-line);
  border-radius: 12px;
  background: var(--pim-surface-flat);
  cursor: pointer;
  overflow: hidden;
  transition: border-color 0.2s ease, background 0.2s ease, translate 0.2s ease;
}

.pim-console-tab:hover { translate: 2px 0; border-color: color-mix(in srgb, var(--pim-tone) 45%, transparent); }

/* The lit edge is on the left here, not the top: the rail reads down the page,
   so the marker for "this one" has to sit on the axis the eye is travelling. */
.pim-console-tab::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 2px;
  background: var(--pim-tone);
  opacity: 0;
  transition: opacity 0.2s ease;
}

/* Real radio, taken out of the layout rather than out of the document: the
   group is arrow-key operable and announced as a group of eight choices, which
   is what it is. */
.pim-console-radio {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
  clip-path: inset(50%);
  pointer-events: none;
}

.pim-console-tab:has(.pim-console-radio:focus-visible) {
  outline: 2px solid var(--pim-spark);
  outline-offset: 2px;
}

.pim-console-tab:has(.pim-console-radio:checked) {
  border-color: color-mix(in srgb, var(--pim-tone) 58%, transparent);
  background:
    linear-gradient(100deg, color-mix(in srgb, var(--pim-tone) 15%, transparent), transparent 72%),
    var(--pim-surface-flat);
  box-shadow: 0 0 26px color-mix(in srgb, var(--pim-tone) 14%, transparent);
}

.pim-console-tab:has(.pim-console-radio:checked)::before { opacity: 0.9; }

.pim-console-glyph {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  flex: none;
  border-radius: 9px;
  color: var(--pim-tone);
  background: linear-gradient(160deg, rgba(30, 62, 122, 0.9), rgba(11, 28, 66, 0.9));
  border: 1px solid color-mix(in srgb, var(--pim-tone) 38%, transparent);
}

.pim-console-glyph .pim-icon { width: 1.1rem; height: 1.1rem; }

/* The chip shares the name's cell and wraps with it: given a column of its own
   it stole width from the name, so "Create your emails" broke over two lines to
   leave room for two words of chip. */
.pim-console-namewrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
}

.pim-console-name {
  font-size: var(--pim-fs-desc);
  font-weight: 500;
  line-height: 1.3;
  color: var(--pim-text);
}

/* Same gold and the same words as the card ribbon it replaces -- the rail has
   no corner to run a diagonal strip across, so the marker becomes a chip. */
.pim-console-beta,
.pim-feature-beta {
  padding: 0.15rem 0.45rem;
  border-radius: 999px;
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pim-tone-gold);
  background: color-mix(in srgb, var(--pim-tone-gold) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--pim-tone-gold) 40%, transparent);
}

.pim-feature-lede {
  margin: 0 0 var(--pim-space-3);
  max-width: 36rem;
}

/* Which panel is showing, for a rail long enough that the selected tab can be
   off the top of the reader's attention. */
.pim-console-cue {
  color: var(--pim-tone);
  opacity: 0;
  transition: opacity 0.2s ease;
}

.pim-console-tab:has(.pim-console-radio:checked) .pim-console-cue { opacity: 0.85; }

.pim-console-panels { min-width: 0; }

/* One panel at a time. `:first-child` is the floor for a browser without
   `:has()`: the section then shows the first run and the rail simply does not
   switch, which is a working page rather than eight hidden panels. The
   `:has()`-gated rule below turns that floor off wherever the switch works,
   and the template's generated rules -- one pseudo-class more specific -- put
   the selected panel back. */
/* The bezel. Same treatment as `.pim-shot-frame`, because this is the same
   kind of object: a light application surface shown on a dark page. */
.pim-console-panel {
  display: none;
  padding: 0.5rem;
  border-radius: 12px;
  border: 1px solid var(--pim-edge);
  background: linear-gradient(180deg, rgba(30, 58, 112, 0.55), rgba(9, 24, 56, 0.85));
  box-shadow: 0 24px 60px -22px rgba(0, 0, 0, 0.85), inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
/* The floor for a browser without `:has()`: the first run, and a rail that does
   not switch. It cannot be the empty panel -- an empty thread whose rail is
   inert is a dead end, where a finished transcript is at least the argument the
   section came to make. */
.pim-console-panel:first-child { display: block; }

/* The feature gate. The selector is deliberately tautological -- every console
   has a `.pim-console-panels` -- so it matches wherever `:has()` is understood
   and nowhere else, which is exactly the set of browsers that can also work the
   rail. It hides every panel; the generated per-run rules in the page template
   and the rule below put back the one to show. */
.pim-console:has(.pim-console-panels) .pim-console-panel { display: none; }

/* Nothing picked yet: the empty panel. `:not(:has(...))` carries two more
   pseudo-classes than the gate, so it wins on specificity, and it stops
   matching the moment a radio is checked. */
.pim-console:not(:has(.pim-console-radio:checked)) .pim-console-panel--empty { display: block; }

/* —— The panel itself ——
   Not the site's palette. The application runs Radix Themes on
   `appearance="light"`, `accent_color="teal"`, `radius="small"`
   (rxconfig.py), which pairs teal with the sage neutral -- so the panel here is
   white with teal accents and near-black text, and the values below are the
   actual Radix light hex codes those tokens resolve to, copied from
   .web/node_modules/@radix-ui/colors. Naming them once at the top means every
   rule below reads the way the application's own stylesheet does
   (`--gray-11` for the tool trace, `--accent-3` for the user bubble) instead of
   as eight hand-picked colours.

   The title bar is the shell chrome's deep navy, which is the one dark surface
   the app actually has, and it does the job of joining a light panel to a dark
   page. The panel sits in the same bezel the screenshots elsewhere on the site
   use, for the same reason: what is inside the frame is the product, what is
   outside it is the page. */
.pim-console-app {
  --app-panel: #ffffff;      /* --color-panel-solid, panel_background=solid */
  --app-accent-2: #f3fbf9;   /* teal-2  */
  --app-accent-3: #e0f8f3;   /* teal-3  */
  --app-accent-6: #a1ded2;   /* teal-6  */
  --app-accent-7: #83cdc1;   /* teal-7  */
  --app-accent-9: #12a594;   /* teal-9  */
  --app-accent-11: #008573;  /* teal-11 */
  --app-accent-12: #0d3d38;  /* teal-12 */
  --app-gray-2: #f7f9f8;     /* sage-2  */
  --app-gray-3: #eef1f0;     /* sage-3  */
  --app-gray-5: #dfe2e0;     /* sage-5  */
  --app-gray-6: #d7dad9;     /* sage-6  */
  --app-gray-7: #cbcfcd;     /* sage-7  */
  --app-gray-11: #5f6563;    /* sage-11 */
  --app-gray-12: #1a211e;    /* sage-12 */
  --app-green-3: #e6f6eb;
  --app-green-9: #30a46c;
  --app-green-11: #218358;
  --app-amber-3: #fff7c2;
  --app-amber-9: #ffc53d;
  --app-amber-11: #ab6400;
  --app-blue-3: #e6f4fe;
  --app-blue-9: #0090ff;
  --app-blue-11: #0d74ce;
  --app-chrome: #152238;     /* the deep_navy chrome preset */
  --app-chrome-text: #e2e8f0;
  /* radius="small": Radix draws its controls at 3-4px, not at the site's 14. */
  --app-radius: 4px;
  /* The panel's reading size. Smaller than the site's body copy on purpose:
     this is a transcript, the application draws it at Radix size 2, and the
     eight runs have to fit their box without a scrollbar. */
  --app-fs: 0.88rem;

  border-radius: 8px;
  background: var(--app-panel);
  overflow: hidden;
  /* A bit less than the screen: the header's 68px, the same air below it, and
     as much again at the bottom, so a panel scrolled to the top of the viewport
     sits inside it with room to breathe rather than running off the fold. The
     ceiling stops it stretching to something absurd on a tall desktop; the
     floor keeps it usable on a short laptop in landscape.

     Fixing the height is also what makes switching jobs still. Every run is the
     same box, so the page does not grow or shrink under the reader as they move
     down the rail -- the long runs scroll inside the thread, exactly as they do
     in the application. */
  display: flex;
  flex-direction: column;

  /* The one number that sets the panel's size: the tallest of the eight runs
     (588px, "Run the import"), so every transcript fits whole and none of them
     shows a scrollbar -- which is why the type inside the panel is a notch
     smaller than the site's and the transcripts are written short. Less than
     The panel lands at 698px, which fits a laptop viewport with room to spare
     -- and it is the same box for all eight, so switching jobs still moves
     nothing.

     `overflow-y: auto` on the thread stays as a safety net rather than a
     feature: a translation that runs longer than the English, or a viewport
     under about 760px, scrolls instead of clipping. */
  --app-thread-h: 592px;
}

.pim-console-bar,
.pim-console-composer { flex: none; }

.pim-console-bar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.85rem;
  background: var(--app-chrome);
}

.pim-console-mark {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: var(--app-radius);
  color: var(--app-accent-6);
  background: color-mix(in srgb, var(--app-accent-9) 30%, transparent);
  border: 1px solid color-mix(in srgb, var(--app-accent-9) 55%, transparent);
}

.pim-console-mark .pim-icon { width: 0.95rem; height: 0.95rem; }

.pim-console-bar-title {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--app-chrome-text);
}

/* Says what this is. Dashed, so it reads as a label on the picture rather than
   as a status the application is reporting: these are written transcripts of
   what the agent does, not a live socket to a demo catalog, and the page is not
   going to let anyone conclude otherwise. */
.pim-console-tag {
  margin-inline-start: auto;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  border: 1px dashed color-mix(in srgb, var(--app-chrome-text) 45%, transparent);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--app-chrome-text) 78%, transparent);
}

/* The thread takes whatever the panel's fixed height leaves after the bar and
   the composer, and scrolls when the run is longer than that -- `min-height: 0`
   because a flex item will not shrink below its content otherwise, which is how
   a long run would push the composer off the bottom instead of scrolling. */
.pim-console-thread {
  flex: none;
  height: var(--app-thread-h);
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  padding: 0.75rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--app-panel);
}

.pim-agentmsg {
  border-radius: 10px;
  padding: 0.5rem 0.7rem;
  word-break: break-word;
}

.pim-agentmsg--user {
  align-self: flex-end;
  max-width: min(100%, 34rem);
  color: var(--app-accent-12);
  background: var(--app-accent-3);
  border: 1px solid var(--app-accent-6);
}

.pim-agentmsg--user p { margin: 0; font-size: var(--app-fs); line-height: 1.45; }

.pim-agentmsg--agent {
  width: 100%;
  display: grid;
  gap: 0.45rem;
  color: var(--app-gray-12);
  background: var(--app-gray-2);
  border: 1px solid var(--app-gray-5);
}

.pim-agentvoice {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-bottom: 0.35rem;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--app-accent-11);
}

/* The turn's status, as the application draws it: a soft Radix badge, green for
   a finished run. */
/* The empty thread, in the application's own words (`agent.log_empty`) and its
   own centred position (`.agent-chat-empty` in assets/agent_chrome.css). The
   second line is this site's, not the app's: without it, a reader who has not
   worked out that the rail is clickable is looking at a blank white box. */
.pim-agentempty {
  margin: auto;
  padding: 1.5rem;
  text-align: center;
  color: var(--app-gray-11);
}

.pim-agentempty p { margin: 0; font-size: var(--app-fs); line-height: 1.5; }

.pim-agentempty-hint {
  margin-top: 0.35rem;
  font-size: 0.78rem;
  color: color-mix(in srgb, var(--app-gray-11) 80%, transparent);
}

/* The wait and the turn it becomes, stacked in one cell: the chip sits at the
   top-left of the space the answer will fill, and that space is held by the
   bubble itself from the first frame, so the arrival costs no reflow. */
.pim-agentturnslot { display: grid; }
.pim-agentturnslot > * { grid-area: 1 / 1; }
/* Both axes: a grid item stretches by default, and without `align-self` the
   chip grew into a blue column the full height of the answer it is standing in
   for. */
.pim-agentturnslot > .pim-agentstatus--running {
  justify-self: start;
  align-self: start;
}

.pim-agentstatus {
  display: inline-flex;
  /* The bubble is a grid, so the badge needs `justify-self` to stop at its own
     width -- `align-self` is the wrong axis and left it a full-width bar. */
  justify-self: start;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  padding: 0.12rem 0.45rem;
  border-radius: var(--app-radius);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.pim-agentdot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
}

.pim-agentstatus--done {
  color: var(--app-green-11);
  background: var(--app-green-3);
}

.pim-agentstatus--done .pim-agentdot { background: var(--app-green-9); }

/* The half-second the panel spends working, in the app's real in-progress
   colours: a blue soft badge saying "Running" (agent.turn.running), with a
   rotating ring where the app puts `rx.spinner`. */
.pim-agentstatus--running {
  color: var(--app-blue-11);
  background: var(--app-blue-3);
}

.pim-agentdot--spin {
  width: 9px;
  height: 9px;
  border: 2px solid var(--app-blue-9);
  border-top-color: transparent;
  background: none;
  animation: pim-run-spin 0.7s linear infinite;
}

@keyframes pim-run-spin { to { rotate: 360deg; } }

/* A run that stopped at a gate. Amber rather than the app's blue "Running",
   because nothing is running -- it is waiting on a person -- and amber is the
   scale the app already spends on "look at this before it goes further". */
.pim-agentstatus--waiting {
  color: var(--app-amber-11);
  background: var(--app-amber-3);
}

.pim-agentstatus--waiting .pim-agentdot {
  background: var(--app-amber-9);
  animation: pim-agent-pulse 1.8s ease-in-out infinite;
}

@keyframes pim-agent-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

.pim-agentline { margin: 0; }

/* The tool trace, verbatim in the application's format: `-> Tool(args) -> n`.
   Monospace and dim, because it is the part a reader skims to believe the rest. */
.pim-agentline--tool {
  font-family: ui-monospace, "SFMono-Regular", "Menlo", "Consolas", monospace;
  font-size: 0.71rem;
  line-height: 1.45;
  color: var(--app-gray-11);
  white-space: pre-wrap;
}

.pim-agentline--text {
  font-size: var(--app-fs);
  line-height: 1.5;
  color: var(--app-gray-12);
}

.pim-agentline code {
  padding: 0.05em 0.3em;
  border-radius: 3px;
  border: 1px solid var(--app-gray-6);
  font-family: ui-monospace, "SFMono-Regular", "Menlo", "Consolas", monospace;
  font-size: 0.86em;
  color: var(--app-accent-11);
  background: var(--app-panel);
}

/* What the agent wrote, as opposed to what it said about writing it. */
.pim-agentline--quote {
  margin: 0;
  padding-inline-start: 0.75rem;
  border-inline-start: 3px solid var(--app-accent-9);
  font-size: var(--app-fs);
  line-height: 1.5;
  color: var(--app-gray-12);
}

.pim-agentline--code {
  margin: 0;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--app-gray-6);
  border-radius: var(--app-radius);
  background: var(--app-panel);
  font-family: ui-monospace, "SFMono-Regular", "Menlo", "Consolas", monospace;
  font-size: 0.7rem;
  line-height: 1.4;
  color: var(--app-gray-12);
  overflow-x: auto;
}

/* The run summary line, in the application's own order: elapsed, tokens,
   rounds, tool calls. */
.pim-agentline--meta {
  padding-top: 0.4rem;
  border-top: 1px dashed var(--app-gray-6);
  font-size: 0.7rem;
  font-style: italic;
  color: var(--app-gray-11);
}

/* —— The run, played ——————————————————————————————————————————————————————
   A panel that has just been chosen was `display: none` a frame ago, and
   animations do not run inside a hidden ancestor: they start from zero when it
   is displayed. That is the whole mechanism -- four delays, no script -- and the
   sequence replays on every pick because every pick is that same transition.

     0      the command arrives as a bubble
     0.44s  the chip appears, "Running"
     1.44s  Running gives way to the answer, which fades in over 0.52s

   Everything is opacity and a 4px lift. Nothing enters or leaves the flow, so
   the thread does not reflow, the run cannot outgrow the box it was measured
   for, and every line is in the accessibility tree and findable by Ctrl-F from
   the first frame: the animation is what the eye sees, not what the document
   contains. */
@keyframes pim-run-in {
  from { opacity: 0; translate: 0 4px; }
  to { opacity: 1; translate: none; }
}

@keyframes pim-run-out {
  from { opacity: 1; }
  to { opacity: 0; }
}

.pim-agentmsg--user,
.pim-agentmsg--agent,
.pim-agentturnslot > .pim-agentstatus--running {
  animation: pim-run-in 0.36s ease-out both;
}

/* The answer takes over from the chip on the same mark: one fades in as the
   other fades out. */
.pim-agentmsg--agent { animation-delay: 1.44s; animation-duration: 0.52s; }
.pim-agentturnslot > .pim-agentstatus--running {
  animation: pim-run-in 0.36s ease-out 0.44s both,
             pim-run-out 0.28s ease-in 1.44s forwards;
}

/* —— The gate ——
   The section's argument, drawn rather than described: the question the agent
   raised, the choices it actually offered, and which one the human picked. The
   box is the application's own choice panel -- accent-2 on an accent-7 hairline
   at 8px (agent_choice_ui.py) -- so a reader who has seen the app recognises
   the thing that stopped the run. */
.pim-agentgate {
  display: grid;
  gap: 0.45rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--app-accent-7);
  border-radius: 8px;
  background: var(--app-accent-2);
}

.pim-agentgate-q {
  margin: 0;
  font-size: var(--app-fs);
  line-height: 1.45;
  color: var(--app-gray-12);
}

.pim-agentgate-q .pim-icon { color: var(--app-accent-9); margin-inline-end: 0.15rem; }

.pim-agentgate-opts { display: flex; flex-wrap: wrap; gap: 0.4rem; }

/* Spans, not buttons: this is a record of a decision that was already taken,
   and a control that cannot be operated should not be drawn as one. They still
   wear the app's button chrome -- outline for the choices, solid accent for the
   one that was clicked. */
.pim-agentgate-opt {
  padding: 0.2rem 0.55rem;
  border-radius: var(--app-radius);
  border: 1px solid var(--app-gray-7);
  background: var(--app-panel);
  font-size: 0.74rem;
  color: var(--app-gray-11);
}

.pim-agentgate-opt.is-picked {
  border-color: transparent;
  background: var(--app-accent-9);
  color: #ffffff;
  font-weight: 600;
}

.pim-agentgate-opt.is-picked::before { content: "\2714"; margin-inline-end: 0.35rem; }

.pim-agentgate-note {
  margin: 0;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--app-gray-11);
}

/* —— The composer ——
   Inert, and `aria-hidden` in the markup. It is here because without it the
   block reads as a chat transcript instead of as the panel this actually is.
   14px and gray-2 on a gray-6 hairline is the app's own composer shell
   (assets/agent_chrome.css). */
.pim-console-composer {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0.75rem 0.75rem;
  padding: 0.4rem 0.45rem 0.4rem 0.75rem;
  border: 1px solid var(--app-gray-6);
  border-radius: 14px;
  background: var(--app-gray-2);
}

.pim-console-composer-text {
  flex: 1;
  font-size: var(--app-fs);
  line-height: 1.35;
  color: var(--app-gray-11);
}

.pim-console-send {
  display: grid;
  place-items: center;
  flex: none;
  width: 27px;
  height: 27px;
  border-radius: var(--app-radius);
  color: #ffffff;
  background: var(--app-accent-9);
}

.pim-console-send .pim-icon { width: 1rem; height: 1rem; rotate: -90deg; }

/* —— Replay console, stacked ——————————————————————————————————————————————
   The console leaves the two-column layout at 1160px rather than at the page's
   960: the shell stops growing at 1160, so below that every pixel comes off the
   panel, the transcripts wrap another line or two, and the runs stop fitting
   their box. Full width buys the prose back -- the panel here is wider than the
   column it replaces, not narrower.

   The rail becomes a scrolling row. Eight names down the side of a phone would
   push the run itself off the screen, and the cue arrow goes with the change:
   it pointed at a panel that is now underneath the rail rather than beside it.
   The selected tab can end up scrolled out of view, which is the cost of the
   row; the panel is directly below it either way. */
@media (max-width: 1160px) {
  .pim-console {
    grid-template-columns: 1fr;
    gap: var(--pim-space-3);
    /* The header wraps to two rows on a phone, so the scroll offset has to
       clear more than the 68px it does on a desktop. */
    scroll-margin-top: 124px;
  }

  .pim-console-rail {
    position: static;
    display: flex;
    gap: 0.5rem;
    overflow-x: auto;
    padding-bottom: 0.35rem;
    scroll-snap-type: x proximity;
  }

  /* Narrow enough that the next name is always half-visible, so the row reads
     as a row that scrolls rather than as two buttons and an edge. */
  .pim-console-tab {
    flex: 0 0 auto;
    max-width: 12.5rem;
    padding: 0.55rem 0.7rem;
    scroll-snap-align: start;
  }

  .pim-console-tab:hover { translate: none; }
  .pim-console-cue { display: none; }
}

/* Below the shell's own width the column narrows for real and the transcripts
   wrap; the box grows with them rather than growing a scrollbar. Two steps are
   enough to cover it -- the phone one is the tallest because a 340px measure
   turns every sentence into four lines. */
@media (max-width: 860px) {
  .pim-console-app { --app-thread-h: 628px; }
}

@media (max-width: 720px) {
  .pim-console-app { --app-thread-h: 736px; }
}

/* —— Narrow ———————————————————————————————————————————————————————————— */
@media (max-width: 960px) {
  /* Nothing about .pim-withnav or the chip row belongs here any more: the row
     is the layout at every width, so the overrides that used to switch to it
     below 960 have moved into the base rules, and the label that used to be
     the first thing dropped here is gone from every width, not just this
     one. */

  /* One column, and the `order` that alternated the bands has to go with it --
     otherwise the band that showed its picture on the left shows it above the
     sentence it illustrates. */
  .pim-showcase { grid-template-columns: 1fr; gap: var(--pim-space-4); }
  .pim-showcase--left .pim-showcase-copy { order: 0; }
  .pim-bands { gap: var(--pim-space-6); }

  .pim-split,
  .pim-contact { grid-template-columns: 1fr; gap: 2rem; }
  .pim-ends { grid-template-columns: 1fr; }
  .pim-end-arrow { rotate: 90deg; justify-self: center; }
  .pim-footer-inner { grid-template-columns: 1fr 1fr; }
  .pim-footer-brand { grid-column: 1 / -1; }
}

@media (max-width: 640px) {
  .pim-menu-toggle { display: inline-flex; align-items: center; gap: .55rem; margin-inline-start: auto; padding: .55rem .7rem; border: 1px solid rgba(129,184,232,.5); border-radius: 4px; color: #fff; background: transparent; cursor: pointer; }
  .pim-menu-toggle > span:first-child { font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
  .pim-menu-icon { width: 18px; height: 14px; position: relative; display: inline-block; }
  .pim-menu-icon i { position: absolute; left: 0; width: 18px; height: 2px; background: currentColor; transition: transform .18s ease, top .18s ease, bottom .18s ease; }
  .pim-menu-icon i:first-child { top: 2px; }.pim-menu-icon i:last-child { bottom: 2px; }
  .pim-menu-toggle.is-open .pim-menu-icon i:first-child { top: 6px; transform: rotate(45deg); }.pim-menu-toggle.is-open .pim-menu-icon i:last-child { bottom: 6px; transform: rotate(-45deg); }
  .pim-nav { display: none; width: 100%; margin: 0; padding: .5rem 0 .8rem; flex-direction: column; gap: 0; }
  body.nav-open .pim-nav { display: flex; }
  .pim-nav a { width: 100%; padding: .75rem .4rem; border-bottom: 1px solid rgba(129,184,232,.16); white-space: normal; }
  /* The ledger's three columns become two: the code keeps the figure company,
     the role goes underneath. */
  .pim-budget-rows li {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .pim-budget-role { grid-column: 1 / -1; order: 1; }

  /* Four columns of arithmetic will not fit. The operator carries the sum, so
     it keeps its row with the base; the resolved value goes underneath, which
     is also the order it is read in. */
  .pim-formula-rows { grid-template-columns: auto auto 1fr; }
  .pim-formula-head--result,
  .pim-formula-result { grid-column: 1 / -1; text-align: right; }

  .pim-specs-rows > div { flex-direction: column; gap: 0.15rem; }
  .pim-specs-rows dd { text-align: left; }

  /* The case study's two two-column rows. Below this the label column costs
     more than it explains, so the verb sits above its node and the source above
     its breadcrumbs. */
  .pim-graph-edge,
  .pim-path {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--pim-space-2);
  }

  .pim-graph-edge::before { display: none; }

  .pim-graph-edges {
    padding-left: 0;
    border-left: 0;
  }


  /* Still a point up from where the whole page used to sit. A phone earns a
     slightly tighter body than a desktop because the measure is short anyway,
     but 16px was the size the review objected to. On `html` for the same
     reason as above -- this has to move the rem, not just the paragraph. */
  html { font-size: 106.25%; } /* 17px */
  .pim-section,
  .pim-bring { padding-block: var(--pim-space-6); }
  .pim-header-inner { flex-wrap: wrap; gap: 0.75rem; padding-block: 0.75rem; }
  .pim-nav { margin-inline-start: 0; width: 100%; }
  .pim-header-cta { margin-inline-start: auto; }
  .pim-tech-summary { letter-spacing: 0.1em; }

  /* The header wraps to two rows here, so it is taller than the 68px the chip
     row sticks below and the two would overlap. Nothing is lost by letting the
     row scroll away on a phone: it is one swipe from the top of the page. */
  .pim-anchors { position: static; }

  /* The bezel is a fixed 8px, which is 4% of a 375px screen on each side. It
     buys less here -- a phone-width screenshot is not a bright slab -- and the
     width it costs matters more, so it thins out. */
  .pim-shot-frame { padding: 0.25rem; border-radius: calc(var(--pim-radius) + 2px); }
  .pim-contact { padding: 1.6rem; }
  .pim-footer-inner { grid-template-columns: 1fr; gap: 1.8rem; }
}
@media (max-width: 900px) { .home-workflow-cards { grid-template-columns: 1fr; gap: 1rem; } .home-workflow-card { min-height: 0; padding: 1.75rem 1.25rem; } }
.pim-pagehero .pim-h1, .page-hero .pim-h1 { font-size: clamp(42px, 4.4vw, 64px); max-inline-size: 18ch; text-wrap: balance; }
@media (max-width: 640px) { .pim-pagehero .pim-h1, .page-hero .pim-h1 { font-size: clamp(38px, 10vw, 48px); } }
@media (min-width: 641px) { .pim-menu-toggle { display: none; } }
@media (prefers-reduced-motion: reduce) { .pim-menu-icon i { transition: none; } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  body::after { animation: none; }
  .pim-card:hover,
  .pim-console-tab:hover,
  .pim-btn:hover { translate: none; }
  .pim-agentstatus--waiting .pim-agentdot { animation: none; }

  /* No staging at all: the run is simply there, which is what this section
     looked like before it learned to play itself. The Running badge has nothing
     to say once the answer is already on screen. */
  .pim-agentmsg--user,
  .pim-agentmsg--agent { animation: none; }
  .pim-agentturnslot > .pim-agentstatus--running { display: none; }
  .pim-link .pim-icon { transition: none; }
  /* The drawer still turns its chevron -- it is the only thing telling the
     reader whether the section is open -- it just stops animating the turn. */
  .pim-tech-marker { transition: none; }
}

/* v10 redesign integration
   The templates deliberately keep the product's real diagrams, screenshots,
   case-study evidence and Agent transcript classes. This layer gives the new
   structural hooks the supplied redesign's visual system while leaving those
   domain components responsible for their own geometry. */
:root {
  --navy: #04162b;
  --navy-2: #071f3d;
  --navy-3: #0a2b50;
  --blue: #208cf1;
  --blue-2: #65b9ff;
  --ice: #f4f7fb;
  --white: #fff;
  --ink: #0c1f37;
  --muted: #5e6e82;
  --line: #dce5ef;
  --line-dark: rgba(133, 185, 232, .24);
  --shadow: 0 18px 45px rgba(8, 27, 52, .08);
  --pim-ink-1: #04162b;
  --pim-ink-2: #071f3d;
  --pim-ink-3: #0a2b50;
  --pim-text: #0c1f37;
  --pim-text-dim: #5e6e82;
  --pim-shell: 1420px;
}

html { font-size: 100%; background: var(--white); }
body { background: var(--white); color: var(--ink); font-family: var(--pim-font-sans); line-height: 1.5; }
button { font: inherit; }
a { color: inherit; }
img { display: block; max-width: 100%; }
.shell, .pim-shell { width: min(1420px, calc(100% - 48px)); max-width: none; margin-inline: auto; padding-inline: 0; }

/* Header */
.site-header, .pim-header { position: sticky; top: 0; z-index: 100; border-bottom: 1px solid rgba(129, 184, 232, .16); background: rgba(4, 22, 43, .97); backdrop-filter: blur(14px); }
.nav-shell, .pim-header-inner { min-height: 72px; height: 72px; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 32px; }
.brand, .pim-brand { display: inline-flex; align-items: center; gap: 12px; color: #fff; font-weight: 900; letter-spacing: -.035em; text-decoration: none; white-space: nowrap; }
.brand-name { font-family: var(--pim-font-brand); font-size: 22px; }
.pim-brand img { width: 34px; height: 34px; object-fit: contain; }
.main-nav, .pim-nav { justify-self: center; display: flex; align-items: center; gap: 28px; margin: 0; color: #c9d8e7; font-size: 13px; font-weight: 650; }
.main-nav a, .pim-nav a { position: relative; padding: 25px 0; border: 0; border-radius: 0; color: #c9d8e7; text-decoration: none; white-space: nowrap; background: transparent; }
.main-nav a::after, .pim-nav a::after { content: ""; position: absolute; left: 0; right: 100%; bottom: 14px; height: 2px; background: var(--blue); transition: right .2s ease; }
.main-nav a:hover, .main-nav a[aria-current="page"], .pim-nav a:hover, .pim-nav a[aria-current="page"] { color: #fff; background: transparent; box-shadow: none; }
.main-nav a:hover::after, .main-nav a[aria-current="page"]::after, .pim-nav a:hover::after, .pim-nav a[aria-current="page"]::after { right: 0; }
.header-actions { display: flex; align-items: center; gap: 10px; }
.mobile-nav-cta { display: none; }
.button, .pim-btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 44px; padding: 0 18px; border: 1px solid transparent; border-radius: 5px; color: var(--ink); font-family: var(--pim-font-sans); font-size: 13px; font-weight: 800; letter-spacing: -.01em; line-height: 1; text-decoration: none; text-transform: none; transition: transform .2s ease, box-shadow .2s ease, background .2s ease; }
.button:hover, .pim-btn:hover { transform: translateY(-1px); translate: none; }
.button-primary, .pim-btn--primary { color: #fff; background: linear-gradient(180deg, #289cff, #137fe0); box-shadow: 0 8px 22px rgba(24, 133, 230, .22); }
.button-primary:hover, .pim-btn--primary:hover { box-shadow: 0 12px 26px rgba(24, 133, 230, .3); }
.button-ghost, .pim-btn--ghost { color: #fff; border-color: #7993ad; background: transparent; }
.button-outline { color: var(--ink); border-color: #bdd1e5; background: #fff; }
.button-outline:hover { background: #f7fbff; }
.pim-header .button-outline { color: #fff; border-color: #7993ad; background: transparent; }
.pim-header .button-outline:hover { background: rgba(30, 62, 122, .45); }
.main-nav .mobile-nav-cta, .pim-nav .mobile-nav-cta { display: none; }
.menu-toggle, .pim-menu-toggle { display: none; }

/* Shared type and dark editorial bands */
h1, h2, h3, p { margin-top: 0; }
h1, h2, .pim-h1, .pim-h2 { font-family: var(--pim-font-display); font-weight: 800; letter-spacing: -.045em; line-height: .94; }
.pim-h1 { font-size: clamp(44px, 5.6vw, 82px); }
.pim-h2 { font-size: clamp(36px, 4.5vw, 64px); }
.eyebrow, .pim-eyebrow { margin-bottom: 14px; color: var(--blue); font-family: var(--pim-font-sans); font-size: 12px; font-weight: 850; letter-spacing: .05em; text-transform: uppercase; text-shadow: none; }
.eyebrow-dark { color: #78c5ff; }
.dark-section, .hero, .page-hero, .pim-pagehero { color: #fff; background-color: var(--navy); }
.page-hero, .pim-pagehero { position: relative; overflow: hidden; padding: 68px 0 62px; border-bottom: 1px solid rgba(129, 184, 232, .16); background-image: linear-gradient(rgba(53, 137, 215, .055) 1px, transparent 1px), linear-gradient(90deg, rgba(53, 137, 215, .055) 1px, transparent 1px), linear-gradient(145deg, var(--navy), var(--navy-2) 65%, var(--navy-3)); background-size: 44px 44px, 44px 44px, auto; }
.page-hero-copy { max-width: 820px; }
.page-hero .pim-lede, .pim-pagehero .pim-lede, .pim-pagehero .pim-hero-support { max-width: 74ch; color: #c0d1e1; }
.pim-pagehero--label { padding-bottom: 38px; }

/* Home: the generated product flow is the visual beside its value proposition. */
.home-hero.pim-flow { display: grid; grid-template-columns: minmax(0, .88fr) minmax(0, 1.12fr); align-items: center; min-height: 590px; padding: 68px max(24px, calc((100% - 1420px) / 2)) 54px; background-color: var(--navy); background-image: linear-gradient(rgba(53, 137, 215, .055) 1px, transparent 1px), linear-gradient(90deg, rgba(53, 137, 215, .055) 1px, transparent 1px), linear-gradient(145deg, var(--navy), var(--navy-2) 65%, var(--navy-3)); background-size: 44px 44px, 44px 44px, auto; }
.home-hero .pim-flow-stage { grid-column: 2; grid-row: 1; width: 100%; max-width: 760px; aspect-ratio: 1160 / 640; filter: none; animation: none; }
.home-hero .pim-flow-payoff { position: relative; left: auto; top: auto; grid-column: 1; grid-row: 1; width: 100%; max-width: 590px; padding: 0; transform: none; text-align: left; background: none; animation: none; }
.home-hero .pim-flow-payoff .pim-lede { max-width: 525px; color: #c0d1e1; font-size: 17px; line-height: 1.72; }
.home-hero .pim-flow-payoff .pim-actions { justify-content: flex-start; margin-top: 28px; }
.home-hero .pim-flow-badge { display: none; }
.home-hero .pim-flow-line { stroke-dashoffset: 0; animation: none; }
.home-hero .pim-flow-spark { animation-delay: 0s, 0s !important; }
.home-hero .pim-flow-node, .home-hero .pim-flow-hub, .home-hero .pim-flow-chip { opacity: 1; animation: none; }
.home-hero .pim-flow-hint, .home-hero .pim-flow-scroll { display: none; }

/* Process sections and truthful showcase diagrams */
.workflow-section, .feature-explorer, .case-index-section, .consult-services, .security-controls, .pricing-plans, .agent-console-area { background: var(--ice); border-bottom: 1px solid var(--line); }
.workflow-section { padding: 0 0 72px; }
.workflow-section > .shell { display: block; }
.workflow-section .section-intro { padding: 68px 0 34px; margin-bottom: 0; }
.workflow-section .section-intro .pim-h2 { text-align: center; }
.workflow-stages, .pim-bands { display: grid; gap: 32px; }
.workflow-stage { padding: 34px; border: 1px solid var(--line); background: var(--white); box-shadow: var(--shadow); }
.workflow-stage .pim-showcase-copy, .workflow-stage .pim-showcase-media { min-width: 0; }
.workflow-stage.pim-showcase--stage { gap: 26px; }
.workflow-stage .pim-showcase-title .pim-h2 { font-size: 34px; }
.workflow-stage .pim-showcase--stage > .pim-showcase-copy > .pim-eyebrow { color: var(--blue); }
.workflow-stage .pim-points-short li { color: var(--ink); }
.product-section, .case-proof, .consult-contact, .security-audit, .pricing-page > section:not(.pricing-hero), .agent-steps, .agent-audit { background: var(--white); }
.product-proof, .product-section { padding-top: 88px; padding-bottom: 80px; }
.product-proof .section-intro, .product-section .section-intro { display: grid; grid-template-columns: 1fr .78fr; gap: 72px; align-items: end; margin-bottom: 42px; }
.product-proof .section-intro > p, .product-section .section-intro > p { max-width: 580px; padding-bottom: 7px; color: var(--muted); font-size: 16px; line-height: 1.72; }
.hero-copy { position: relative; z-index: 1; }
.workflow-grid { width: 100%; }
.product-audiences { margin-top: 28px; }
.product-shot { min-width: 0; }
.feature-card { min-width: 0; }

/* First-class feature and case surfaces */
.feature-explorer, .case-explorer { padding-top: 0; }
.feature-process-ribbon, .case-navigation, .pim-anchors { top: 72px; margin-inline: 0; padding: 14px 0; border-bottom: 1px solid var(--line); background: rgba(244, 247, 251, .96); box-shadow: none; backdrop-filter: blur(12px); }
.feature-process-ribbon ul, .case-navigation ul, .pim-anchors ul { gap: 8px; }
.feature-process-ribbon a, .case-navigation a, .pim-anchors a { padding: 8px 12px; border: 1px solid var(--line); border-radius: 4px; color: var(--muted); font-size: 12px; letter-spacing: 0; text-transform: none; background: var(--white); }
.feature-process-ribbon a:hover, .case-navigation a:hover, .pim-anchors a:hover { color: var(--blue); border-color: #9bc8ea; background: #fff; }
.feature-sections, .case-beats { gap: 28px; padding: 52px 0 82px; }
.feature-panel, .case-panel, .security-card-grid .pim-card, .case-grid .pim-study, .pricing-grid .pim-plan, .service-grid .pim-card { border: 1px solid var(--line); border-radius: 0; background: var(--white); box-shadow: var(--shadow); }
.feature-panel, .case-panel { padding: 34px; }
.feature-panel .pim-feature-head, .case-panel .pim-feature-head { border-bottom-color: var(--line); }
.feature-panel-body, .case-panel-body { color: var(--ink); }
.feature-panel .pim-def dt, .case-panel .pim-def dt { color: var(--ink); }
.feature-panel .pim-def dd, .case-panel .pim-def dd { color: var(--muted); }
.feature-page-hero { background-color: var(--navy); }
.feature-rail { min-width: 0; }
.case-detail { background: var(--white); }
.case-index { background: var(--white); }
.case-paths, .case-records, .case-renders, .case-rules, .case-graph, .case-formula, .case-sku, .case-tiers, .case-budget, .case-specs { min-width: 0; }
.case-records, .case-renders, .case-tiers { display: grid; gap: 20px; }
.case-specs, .case-formula, .case-budget { background: var(--white); }
.case-grid, .security-card-grid, .service-grid, .pricing-grid { gap: 20px; }
.case-grid .pim-study, .security-card-grid .pim-card, .service-grid .pim-card, .pricing-grid .pim-plan { padding: 28px; }
.case-grid .pim-study { border-top: 2px solid var(--pim-tone); }

/* Useful-size screenshot frames; image pixels remain unchanged. */
.pim-shot-frame, .product-shot-frame { padding: 8px; border: 1px solid #173b61; border-radius: 5px; background: var(--navy); box-shadow: 0 18px 45px rgba(8, 27, 52, .16); }
.pim-shot-frame img, .product-shot-frame img { display: block; width: 100%; height: auto; border-radius: 2px; background: #fff; }
.pim-shot figcaption { color: var(--muted); }

/* Pricing, consultation and trust are redesign page types, not recoloured old cards. */
.pricing-page .pricing-hero .page-hero-copy { max-width: 880px; }
.pricing-card.pim-plan { min-height: 100%; }
.pricing-card .pim-pill { color: var(--blue); background: #eef7ff; border: 1px solid #bddcf3; border-radius: 4px; text-shadow: none; }
.pricing-card .pim-plan-summary, .pricing-card .pim-ticks li, .consult-contact .pim-lede, .consult-contact .pim-ticks li { color: var(--muted); }
.pricing-card.pim-plan--featured { border-color: var(--blue); box-shadow: 0 18px 45px rgba(32, 140, 241, .14); }
.pricing-card .pim-btn--ghost { color: var(--ink); border-color: #9fb5ca; background: var(--white); }
.pricing-card .pim-btn--ghost:hover { border-color: var(--blue); background: #eef7ff; }
.consult-contact-layout, .pim-contact { border: 1px solid var(--line); border-radius: 0; background: var(--ice); box-shadow: var(--shadow); }
.consult-contact-layout .pim-btn { margin-top: 24px; }
.security-audit .pim-tech { border: 1px solid var(--line); border-radius: 0; background: var(--ice); }
.security-audit .pim-tech-summary { color: var(--blue); }
.security-page { background: var(--white); }

/* Agent: the real docked panel is the product visual. */
.agent-console-area { padding-top: 70px; padding-bottom: 82px; }
.agent-console-area > .shell > .section-intro { margin-bottom: 38px; }
.agent-task-rail, .pim-console-rail { gap: 8px; }
.agent-task-rail .pim-console-tab, .pim-console-rail .pim-console-tab { border-radius: 4px; border-color: var(--line); background: var(--white); }
.agent-task-rail .pim-console-tab:hover, .pim-console-rail .pim-console-tab:hover { translate: none; border-color: #9bc8ea; }
.agent-run-panels .pim-console-panel, .pim-console-panels .pim-console-panel { border-radius: 5px; border-color: #173b61; background: var(--navy); box-shadow: 0 18px 45px rgba(8, 27, 52, .16); }
.agent-app-shell.pim-console-app { border-radius: 2px; }
.agent-console { min-width: 0; }
.agent-console-section { min-width: 0; }
.agent-page-hero { background-color: var(--navy); }
.agent-run-panel { min-width: 0; }
.agent-app-bar { min-width: 0; }
.agent-thread { min-width: 0; }
.agent-gate { min-width: 0; }
.agent-steps-grid { min-width: 0; }
.agent-steps, .agent-audit { border-top: 1px solid var(--line); }
.agent-audit .pim-def { border-left-color: var(--blue); }
/* The first replay is the useful no-selection fallback when a browser does
   not expose :has(), and also prevents an empty-looking console before the
   first radio change. */
.pim-console:not(:has(.pim-console-radio:checked)) .pim-console-panel--empty { display: none; }
.pim-console:not(:has(.pim-console-radio:checked)) .pim-console-panel:first-child { display: block; }

/* Footer */
.footer, .pim-footer { border-top: 0; background: var(--navy); color: #fff; padding: 64px 0 22px; }
.footer-grid, .pim-footer-inner { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 60px; }
.footer-column { min-width: 0; }
.footer-brand p, .pim-footer-brand p { max-width: 42ch; color: #aebfd0; }
.footer-heading, .pim-footer-heading { margin: 0 0 18px; color: #78c5ff; font-size: 12px; font-weight: 850; letter-spacing: .05em; text-transform: uppercase; }
.footer a, .pim-footer a { color: #c9d8e7; }
.footer a:hover, .pim-footer a:hover { color: #fff; }
.pim-footer-list { gap: 10px; }
.footer-bottom, .pim-footer-legal { margin-top: 52px; padding-top: 18px; border-top: 1px solid rgba(129, 184, 232, .16); color: #8fa7bc; }
.footer-legal-links, .pim-footer-legal-links { gap: 18px; }

/* Responsive rhythm: value proposition first on mobile and horizontal Agent selector. */
@media (max-width: 900px) {
  /* Three columns rather than two, so the switcher can sit beside the burger
     instead of being auto-placed onto a row of its own under it. Both are
     pinned to row 1 explicitly: the nav between them spans the full width and
     would otherwise push whatever follows it onto a third row. */
  .nav-shell, .pim-header-inner { height: auto; min-height: 64px; grid-template-columns: 1fr auto auto; gap: 12px; padding-block: 12px; }
  .pim-langs { grid-row: 1; grid-column: 2; }
  .menu-toggle, .pim-menu-toggle { grid-row: 1; grid-column: 3; }
  .menu-toggle, .pim-menu-toggle { display: inline-flex; align-items: center; justify-content: space-between; gap: 10px; min-width: 82px; padding: 10px 12px; border: 1px solid rgba(129, 184, 232, .5); border-radius: 4px; color: #fff; background: transparent; cursor: pointer; }
  .menu-label { font-size: 11px; font-weight: 800; letter-spacing: .02em; }
  .main-nav, .pim-nav { grid-column: 1 / -1; justify-self: stretch; width: 100%; gap: 0; }
  html:not(.js) .main-nav, html:not(.js) .pim-nav { display: flex; flex-direction: column; align-items: stretch; }
  .js .main-nav, .js .pim-nav { display: none; }
  .js body.nav-open .main-nav, .js body.nav-open .pim-nav { display: flex; flex-direction: column; align-items: stretch; }
  .main-nav a, .pim-nav a { width: 100%; padding: 14px 2px; border-bottom: 1px solid rgba(132, 183, 229, .13); font-size: 15px; }
  .main-nav a::after, .pim-nav a::after { bottom: 6px; }
  .header-actions { display: none; }
  .header-actions .button-outline { display: none; }
  .main-nav .mobile-nav-cta, .pim-nav .mobile-nav-cta { display: inline-flex; width: auto; margin-top: 12px; padding: 14px 18px; border: 0; color: #fff; background: linear-gradient(180deg, #289cff, #137fe0); }
  .main-nav .mobile-nav-cta::after, .pim-nav .mobile-nav-cta::after { display: none; }
  .home-hero.pim-flow { display: flex; flex-direction: column; align-items: stretch; gap: 34px; min-height: 0; padding: 58px 24px 54px; }
  .home-hero .pim-flow-payoff { order: 1; max-width: none; }
  .home-hero .pim-flow-stage { order: 2; max-width: none; }
  .product-proof .section-intro, .product-section .section-intro { grid-template-columns: 1fr; gap: 22px; }
  .workflow-stage { padding: 26px; }
  .feature-panel, .case-panel { padding: 26px; }
  .footer-grid, .pim-footer-inner { grid-template-columns: 1fr 1fr; gap: 34px; }
  .footer-brand, .pim-footer-brand { grid-column: 1 / -1; }
}
@media (max-width: 640px) {
  .shell, .pim-shell, .pim-header .pim-shell { width: calc(100% - 32px); }
  .home-hero.pim-flow { padding-inline: 16px; }
  .home-hero .pim-flow-payoff .pim-lede { font-size: 16px; }
  .pim-h1 { font-size: 42px; }
  .pim-h2 { font-size: 36px; }
  .page-hero, .pim-pagehero { padding: 52px 0 46px; }
  .workflow-section .section-intro { padding-top: 52px; }
  .workflow-stage, .feature-panel, .case-panel { padding: 20px; }
  .feature-process-ribbon, .case-navigation, .pim-anchors { position: static; }
  .feature-process-ribbon ul, .case-navigation ul, .pim-anchors ul { flex-wrap: nowrap; overflow-x: auto; justify-content: flex-start; }
  /* On the li as well as the a: the li is the flex item, and on its own the
     a's flex value does nothing to stop the item shrinking under it. */
  .feature-process-ribbon ul > li, .case-navigation ul > li, .pim-anchors ul > li { flex: 0 0 auto; }
  .feature-process-ribbon a, .case-navigation a, .pim-anchors a { flex: 0 0 auto; }
  .footer-grid, .pim-footer-inner { grid-template-columns: 1fr; gap: 28px; }
  .footer-brand, .pim-footer-brand { grid-column: auto; }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
  .reveal { opacity: 1 !important; transform: none !important; translate: none !important; }
}

/* Scoped warmth and page-type refinements
   These tokens are intentionally late and local to the redesign surfaces that
   need less stark contrast. The application screenshots, Agent chrome and
   case-detail evidence keep their own source-accurate treatment. */
:root {
  --stone-bg: #eee9e1;
  --stone-surface: #f8f4ee;
  --stone-surface-strong: #e7dfd4;
  --stone-line: #d7cdc0;
  --stone-muted: #68717a;
  --workflow-ingest: #08796d;
  --workflow-enrich: #a15d1a;
  --workflow-publish: #ad3d60;
}

/* Homepage product proof and the reusable bring-a-file band. */
.product-proof.product-section,
.product-section { background: var(--stone-bg); border-block: 1px solid var(--stone-line); }
.product-proof .section-intro > p,
.product-section .section-intro > p { color: var(--stone-muted); }
.product-audiences .pim-card {
  border-color: var(--stone-line);
  background: var(--stone-surface);
  box-shadow: 0 12px 30px rgba(72, 58, 42, .07);
}
.product-audiences .pim-card:hover { border-color: color-mix(in srgb, var(--pim-tone) 46%, var(--stone-line)); box-shadow: 0 16px 34px rgba(72, 58, 42, .1); }
.product-audiences .pim-card-glyph,
.bring-file .pim-card-glyph,
.pim-bring .pim-card-glyph {
  width: 48px;
  height: 48px;
  color: color-mix(in srgb, var(--pim-tone) 40%, #243247);
  background: color-mix(in srgb, var(--pim-tone) 28%, var(--stone-surface));
  border-color: color-mix(in srgb, var(--pim-tone) 50%, var(--stone-line));
}
.bring-file,
.pim-bring {
  color: var(--ink);
  border-block-color: var(--stone-line);
  background: var(--stone-bg);
  background-image: linear-gradient(rgba(126, 107, 85, .045) 1px, transparent 1px), linear-gradient(90deg, rgba(126, 107, 85, .045) 1px, transparent 1px);
  background-size: 44px 44px;
}
.bring-file .pim-h2,
.pim-bring .pim-h2,
.bring-file > .pim-shell > .pim-heading .pim-h2,
.pim-bring > .pim-shell > .pim-heading .pim-h2 { color: var(--ink); }
.bring-file .pim-lede,
.pim-bring .pim-lede,
.bring-file .pim-note,
.pim-bring .pim-note,
.bring-file .pim-bring-privacy,
.pim-bring .pim-bring-privacy { color: var(--stone-muted); }
.bring-file > .pim-shell > .pim-heading .pim-lede,
.pim-bring > .pim-shell > .pim-heading .pim-lede { color: var(--stone-muted); }
.bring-file .pim-card,
.pim-bring .pim-card {
  border-color: var(--stone-line);
  background: var(--stone-surface);
  box-shadow: 0 12px 30px rgba(72, 58, 42, .07);
}
.bring-file .pim-btn--ghost,
.pim-bring .pim-btn--ghost { color: var(--ink); border-color: #9d9183; background: transparent; }
.bring-file .pim-btn--ghost:hover,
.pim-bring .pim-btn--ghost:hover { background: var(--stone-surface); border-color: var(--ink); }

/* Home workflow cadence. The modifiers are semantic accents supplied by the
   home template; every visual accent in a card reads from the same variable. */
.home-workflow-card {
  --workflow-accent: var(--blue);
  --workflow-wash: var(--white);
  border-color: color-mix(in srgb, var(--workflow-accent) 25%, var(--line));
  background: var(--workflow-wash);
  box-shadow: 0 12px 30px rgba(8, 27, 52, .06);
}
.home-workflow-card--ingest { --workflow-accent: var(--workflow-ingest); --workflow-wash: #edf6f3; }
.home-workflow-card--enrich { --workflow-accent: var(--workflow-enrich); --workflow-wash: #faf2e7; }
.home-workflow-card--publish { --workflow-accent: var(--workflow-publish); --workflow-wash: #faedf1; }
.home-workflow-card .home-workflow-step {
  color: var(--workflow-accent);
  -webkit-text-stroke-color: var(--workflow-accent);
}
.home-workflow-card .home-workflow-rule { background-color: var(--workflow-accent); }
.home-workflow-card .home-workflow-visual { color: var(--workflow-accent); }
.home-workflow-card .home-workflow-rule { background: var(--workflow-accent); }
.home-workflow-card .pim-h2 { color: var(--workflow-accent); }
.home-workflow-card .home-workflow-link { color: var(--workflow-accent); }
.home-workflow-card .home-workflow-link:hover { color: color-mix(in srgb, var(--workflow-accent) 72%, #0c1f37); }
.home-workflow-card .home-workflow-visual svg { stroke: currentColor; }

/* Feature disclosures stay native <details>, but now belong to the light
   feature panel rather than reading as a translucent dark drawer. */
.feature-panel .pim-card-glyph {
  width: 48px;
  height: 48px;
  color: color-mix(in srgb, var(--pim-tone) 40%, #243247);
  background: color-mix(in srgb, var(--pim-tone) 28%, var(--stone-surface));
  border-color: color-mix(in srgb, var(--pim-tone) 50%, var(--stone-line));
}
.feature-panel .pim-tech {
  border-color: color-mix(in srgb, var(--pim-tone) 48%, var(--stone-line));
  background: color-mix(in srgb, var(--pim-tone) 14%, var(--stone-surface));
}
.feature-panel .pim-tech-summary {
  color: color-mix(in srgb, var(--pim-tone) 40%, #243247);
  background: transparent;
}
.feature-panel .pim-tech-summary:hover { background: color-mix(in srgb, var(--pim-tone) 18%, var(--stone-surface)); }
.feature-panel .pim-tech[open] .pim-tech-summary { border-bottom-color: var(--stone-line); }
.feature-panel .pim-tech-marker {
  color: color-mix(in srgb, var(--pim-tone) 40%, #243247);
  border-color: color-mix(in srgb, var(--pim-tone) 52%, var(--stone-line));
}
.feature-panel .pim-tech-body { color: var(--ink); }

/* Services use the same tone-derived glyph language as features. */
.service-grid .pim-card-glyph {
  width: 48px;
  height: 48px;
  color: color-mix(in srgb, var(--pim-tone) 40%, #243247);
  background: color-mix(in srgb, var(--pim-tone) 28%, var(--stone-surface));
  border-color: color-mix(in srgb, var(--pim-tone) 50%, var(--stone-line));
}

/* Compact case index: four related studies across the wide shell, then a
   deliberate 2/1 cadence as the available width decreases. Detail panels are
   untouched by this scope. */
.case-grid.pim-studies {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
}
.case-grid .pim-study,
.case-grid .case-card {
  min-width: 0;
  min-height: 260px;
  padding: 20px;
  border-color: var(--stone-line);
  border-top-color: color-mix(in srgb, var(--pim-tone) 58%, var(--stone-line));
  background: var(--stone-surface);
  box-shadow: 0 10px 26px rgba(72, 58, 42, .06);
}
.case-grid .pim-study .pim-card-glyph,
.case-grid .case-card .pim-card-glyph {
  color: color-mix(in srgb, var(--pim-tone) 40%, #263549);
  background: color-mix(in srgb, var(--pim-tone) 18%, var(--stone-surface));
  border-color: color-mix(in srgb, var(--pim-tone) 38%, var(--stone-line));
}
.case-grid .pim-study-headline,
.case-grid .pim-study .pim-study-headline,
.case-grid .case-card .pim-study-headline { color: var(--ink); }
.case-grid .pim-study .pim-study-summary,
.case-grid .case-card .pim-study-summary { color: var(--stone-muted); }
.case-grid .pim-study .pim-study-link,
.case-grid .case-card .pim-study-link { color: color-mix(in srgb, var(--pim-tone) 38%, #243247); }
.case-grid .pim-study .editorial-media,
.case-grid .pim-study .case-image { height: 132px; overflow: hidden; background: var(--stone-surface-strong); }
.case-grid .pim-study .editorial-media img,
.case-grid .pim-study .case-image img { width: 100%; height: 100%; object-fit: cover; }
.case-editorial .editorial-media > img { max-height: 380px; }

/* Agent page is intentionally compact before the actual docked panel. */
.agent-page-hero { padding: 44px 0 18px; }
.pim-page--agent .agent-page-hero { padding: 44px 0 18px; border-bottom: 0; }
.agent-console-area { padding: 36px 0 64px; }
.pim-page--agent .agent-console-area { padding: 36px 0 64px; }
.agent-console-area > .shell > .section-intro { gap: 24px; margin-bottom: 24px; }
.agent-console-area > .shell > .section-intro .pim-h2 {
  max-width: 20ch;
  font-size: clamp(30px, 3.2vw, 46px);
}

/* Pricing keeps equal-height plans while shifting the cards to the warmer
   neutral surface. */
.pricing-hero { padding: 40px 0 22px; }
.pricing-page .pricing-hero { padding: 40px 0 22px; }
.pricing-plans { padding: 24px 0 72px; background: var(--ice); }
.pricing-page #engagements { padding-top: 24px; }
.pricing-card.pim-plan {
  min-height: 100%;
  padding: 24px;
  border: 1px solid var(--stone-line);
  border-radius: 8px;
  background: var(--stone-surface);
  box-shadow: 0 12px 30px rgba(72, 58, 42, .07);
}
.pricing-card.pim-plan--featured {
  border-color: #83b9e7;
  background: #f0f7fd;
  box-shadow: 0 16px 34px rgba(32, 140, 241, .12);
}
.pricing-card .pim-plan-summary,
.pricing-card .pim-ticks li { color: var(--stone-muted); }

@media (max-width: 1120px) {
  .case-grid.pim-studies { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .case-grid.pim-studies { grid-template-columns: 1fr; }
  .agent-page-hero { padding: 36px 0 18px; }
  .agent-console-area { padding: 30px 0 52px; }
  .pricing-hero { padding: 34px 0 20px; }
  .pricing-plans { padding-top: 20px; }
}

/* Restrained technical palette
   Shared surfaces stay cool and quiet; the only strong step accent is the
   same steel blue used by the product UI. Existing stone, Agent and editorial
   image treatments intentionally remain outside these scopes. */
:root {
  --technical-blue: #2f78b7;
  --technical-blue-dark: #245d8d;
  --technical-ink: #1b2a3b;
  --technical-surface: #f5f7fa;
  --technical-surface-alt: #eef3f7;
  --technical-line: #d7dee7;
}

/* The three steps share one accent. Their identities come from restrained
   technical texture rather than three competing hues. */
.home-workflow-card {
  position: relative;
  --workflow-accent: var(--technical-blue);
  --workflow-wash: var(--technical-surface);
  border-color: var(--technical-line);
  background-color: var(--workflow-wash);
}
.home-workflow-card--ingest,
.home-workflow-card--enrich,
.home-workflow-card--publish {
  --workflow-accent: var(--technical-blue);
  --workflow-wash: var(--technical-surface);
}
.home-workflow-card--ingest {
  background-image: radial-gradient(circle at 92% 10%, rgba(47, 120, 183, .12) 0 1px, transparent 1.5px);
  background-size: 12px 12px;
}
.home-workflow-card--enrich .home-workflow-visual {
  background-image: linear-gradient(rgba(105, 128, 148, .1) 1px, transparent 1px), linear-gradient(90deg, rgba(105, 128, 148, .1) 1px, transparent 1px);
  background-size: 14px 14px;
}
.home-workflow-card--publish .home-workflow-visual { position: relative; }
.home-workflow-card--publish .home-workflow-visual::before {
  content: "";
  position: absolute;
  inset: 10px 12%;
  border-block: 1px solid rgba(47, 120, 183, .2);
  background: linear-gradient(90deg, transparent 0 12%, rgba(47, 120, 183, .16) 12% 13%, transparent 13% 49%, rgba(47, 120, 183, .16) 49% 50%, transparent 50% 86%, rgba(47, 120, 183, .16) 86% 87%, transparent 87%);
  pointer-events: none;
}
.home-workflow-card .home-workflow-step,
.home-workflow-card .home-workflow-rule,
.home-workflow-card .home-workflow-visual,
.home-workflow-card .home-workflow-link,
.home-workflow-card .pim-h2 { color: var(--technical-blue-dark); }
.home-workflow-card .home-workflow-step { -webkit-text-stroke-color: var(--technical-blue); }
.home-workflow-card .home-workflow-rule { background: var(--technical-blue); }
.home-workflow-card .home-workflow-visual svg { position: relative; z-index: 1; stroke: var(--technical-blue-dark); }
.home-workflow-card .home-workflow-link { color: var(--technical-blue-dark); }

/* Case index cards use one neutral technical treatment; tone classes remain in
   the markup for content/data compatibility but no longer drive card colour. */
.case-grid.pim-studies .pim-study,
.case-grid.pim-studies .case-card {
  border-color: var(--technical-line);
  border-top: 2px solid #6c849b;
  background: #f7f8fa;
  box-shadow: 0 10px 26px rgba(27, 42, 59, .06);
}
.case-grid.pim-studies .pim-study .pim-card-glyph,
.case-grid.pim-studies .case-card .pim-card-glyph {
  color: #365b7a;
  background: #e7edf3;
  border-color: #c5d2df;
}
.case-grid.pim-studies .pim-study-headline,
.case-grid.pim-studies .pim-study-summary { color: var(--technical-ink); }
.case-grid.pim-studies .pim-study-summary { color: #526477; }
.case-grid.pim-studies .pim-study-link { color: var(--technical-blue-dark); }

/* Case-proof intro: the title and answer share one deliberate row. The index
   intro stays a conventional full-width heading above the four studies. */
.pim-studies-intro { display: block; margin-bottom: 32px; }
.pim-studies-intro .section-intro,
.pim-studies-intro .pim-heading { margin-bottom: 0; }
.pim-studies-intro .pim-h2 { max-width: 15ch; text-align: left; }

.case-proof-intro { margin-bottom: 32px; }
.case-proof-intro .section-intro,
.case-proof-intro .pim-heading {
  display: grid;
  grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr);
  align-items: end;
  gap: 10px 56px;
  margin-bottom: 0;
}
.case-proof-intro .pim-eyebrow { grid-column: 1 / -1; }
.case-proof-intro .pim-h2 { grid-column: 1; margin-bottom: 0; text-align: left; }
.case-proof-intro .pim-lede {
  grid-column: 2;
  max-width: 66ch;
  margin: 0;
  color: #526477;
  line-height: 1.65;
}

/* Pricing plans share a neutral base; Basic is distinguished only by a quiet
   blue rule and cool surface. */
.pricing-grid .pricing-card.pim-plan {
  border-color: var(--technical-line);
  background: #f8f9fb;
  box-shadow: 0 12px 28px rgba(27, 42, 59, .07);
}
.pricing-grid .pricing-card .pim-pill {
  color: #4b6278;
  border-color: #c3ced9;
  background: #e9eef3;
  text-shadow: none;
}
.pricing-grid .pricing-card.pim-plan--featured {
  border: 1px solid #9fc2df;
  border-top: 2px solid var(--technical-blue);
  background: #f1f6fa;
  box-shadow: 0 12px 28px rgba(27, 42, 59, .08);
}
.pricing-grid .pricing-card .pim-icon--tick { color: #668099; }

/* Lighting's case walk uses a single technical accent. Images remain entirely
   source-accurate; only navigation and panel chrome are unified. */
.case-detail--lighting .case-navigation a {
  color: #365b7a;
  border-color: #c5d2df;
  background: #eef3f7;
}
.case-detail--lighting .case-navigation a:hover {
  color: var(--technical-blue-dark);
  border-color: #7fa7c7;
  background: #e5eef5;
}
.case-detail--lighting .case-panel {
  --pim-tone: #5a7893;
  border-top: 2px solid #6c849b;
  border-color: var(--technical-line);
  background: #f8f9fb;
}
.case-detail--lighting .case-panel .pim-feature-head { border-bottom-color: var(--technical-line); }
.case-detail--lighting .case-panel .pim-card-glyph {
  color: #365b7a;
  background: #e7edf3;
  border-color: #c5d2df;
}
.case-detail--lighting .case-panel .pim-case-step,
.case-detail--lighting .case-panel .pim-link { color: var(--technical-blue-dark); }

@media (max-width: 820px) {
  .case-proof-intro .section-intro,
  .case-proof-intro .pim-heading {
    grid-template-columns: 1fr;
    gap: 14px;
    align-items: start;
  }
  .case-proof-intro .pim-eyebrow,
  .case-proof-intro .pim-h2,
  .case-proof-intro .pim-lede { grid-column: 1; }
}

/* Lighting case: a cool steel reading for the page field and its technical
   records.  These variables deliberately live on the case modifier so the
   other case studies retain their own tones and editorial treatment. */
.case-detail--lighting {
  --lighting-ink: #1b2a3b;
  --lighting-muted: #586a7b;
  --lighting-page: #edf2f6;
  --lighting-surface: #f8fafc;
  --lighting-surface-alt: #e8eef3;
  --lighting-line: #c6d1dc;
  --lighting-line-strong: #8ba1b5;
  --lighting-accent: #3d6f96;
  --lighting-accent-dark: #285777;
  background: var(--lighting-page);
}

.case-detail--lighting .case-editorial,
.case-detail--lighting .case-explorer,
.case-detail--lighting .case-beats {
  color: var(--lighting-ink);
  background: var(--lighting-page);
}

.case-detail--lighting .case-editorial {
  border-top: 1px solid var(--lighting-line);
  border-bottom: 1px solid var(--lighting-line);
  background: var(--lighting-surface-alt);
}

.case-detail--lighting .editorial-media {
  border-color: var(--lighting-line);
  background: var(--lighting-surface);
  box-shadow: 0 12px 28px rgba(27, 42, 59, .08);
}

.case-detail--lighting .editorial-media figcaption,
.case-detail--lighting .editorial-gallery figcaption {
  color: var(--lighting-muted);
}

.case-detail--lighting .editorial-gallery img {
  border-color: var(--lighting-line);
  background: var(--lighting-surface);
}

.case-detail--lighting .case-navigation,
.case-detail--lighting .case-navigation ul {
  border-color: var(--lighting-line);
  background: rgba(237, 242, 246, .96);
}

.case-detail--lighting .case-navigation a {
  color: var(--lighting-accent-dark);
  border-color: var(--lighting-line);
  background: var(--lighting-surface);
}

.case-detail--lighting .case-navigation a:hover,
.case-detail--lighting .case-navigation a:focus-visible {
  color: var(--lighting-accent-dark);
  border-color: var(--lighting-line-strong);
  background: var(--lighting-surface-alt);
}

.case-detail--lighting .case-panel {
  --pim-tone: var(--lighting-accent);
  color: var(--lighting-ink);
  border: 1px solid var(--lighting-line);
  border-top: 2px solid var(--lighting-accent);
  background: var(--lighting-surface);
  box-shadow: 0 14px 30px rgba(27, 42, 59, .08);
}

.case-detail--lighting .case-panel .pim-feature-head {
  border-bottom-color: var(--lighting-line);
}

.case-detail--lighting .case-panel .pim-h2,
.case-detail--lighting .case-panel .pim-h3,
.case-detail--lighting .case-panel .pim-def dt {
  color: var(--lighting-ink);
}

.case-detail--lighting .case-panel .pim-card-glyph {
  color: var(--lighting-accent-dark);
  border-color: var(--lighting-line-strong);
  background: var(--lighting-surface-alt);
  box-shadow: none;
}

.case-detail--lighting .case-panel .pim-case-step,
.case-detail--lighting .case-panel .pim-link,
.case-detail--lighting .case-panel a {
  color: var(--lighting-accent-dark);
}

.case-detail--lighting .case-panel .pim-lede,
.case-detail--lighting .case-panel-body > p:not(.pim-lede),
.case-detail--lighting .case-panel .pim-def dd,
.case-detail--lighting .case-panel .pim-tech-body > p {
  color: var(--lighting-muted);
}

.case-detail--lighting .case-panel .pim-def {
  border-left-color: var(--lighting-line-strong);
}

/* Keep the disclosure native and keyboard-operable, but make its closed and
   open states part of the same light technical surface as the records. */
.case-detail--lighting .case-panel .pim-tech {
  border-color: var(--lighting-line);
  border-radius: 8px;
  background: var(--lighting-surface-alt);
}

.case-detail--lighting .case-panel .pim-tech-summary {
  color: var(--lighting-accent-dark);
}

.case-detail--lighting .case-panel .pim-tech-summary:hover,
.case-detail--lighting .case-panel .pim-tech-summary:focus-visible {
  color: var(--lighting-ink);
  background: #dde7ee;
}

.case-detail--lighting .case-panel .pim-tech[open] .pim-tech-summary {
  border-bottom-color: var(--lighting-line);
}

.case-detail--lighting .case-panel .pim-tech-marker {
  border-color: var(--lighting-line-strong);
  color: var(--lighting-accent-dark);
}

.case-detail--lighting .case-panel .pim-tech-body {
  color: var(--lighting-ink);
}

.case-detail--lighting .case-panel .pim-optrec,
.case-detail--lighting .case-panel .pim-tier,
.case-detail--lighting .case-panel .pim-graph-hub,
.case-detail--lighting .case-panel .pim-graph-reverse,
.case-detail--lighting .case-panel .pim-render {
  border-color: var(--lighting-line);
  background: var(--lighting-surface);
}

.case-detail--lighting .case-panel .pim-optrec,
.case-detail--lighting .case-panel .pim-render {
  border-top-color: var(--lighting-accent);
}

.case-detail--lighting .case-panel .pim-graph-reverse {
  border-top-color: var(--lighting-line-strong);
}

.case-detail--lighting .case-panel .pim-tier,
.case-detail--lighting .case-panel .pim-path {
  border-left-color: var(--lighting-accent);
}

.case-detail--lighting .case-panel .pim-optrec-head,
.case-detail--lighting .case-panel .pim-graph-reverse header {
  border-bottom-color: var(--lighting-line);
}

.case-detail--lighting .case-panel .pim-optrec-code,
.case-detail--lighting .case-panel .pim-sku-code {
  color: var(--lighting-accent-dark);
  border-color: var(--lighting-line);
  background: var(--lighting-surface-alt);
}

.case-detail--lighting .case-panel .pim-optrec-arrow,
.case-detail--lighting .case-panel .pim-optrec-dim,
.case-detail--lighting .case-panel .pim-optrec-rows dt,
.case-detail--lighting .case-panel .pim-tier-sub,
.case-detail--lighting .case-panel .pim-tier-note,
.case-detail--lighting .case-panel .pim-sku-label,
.case-detail--lighting .case-panel .pim-sku-dash,
.case-detail--lighting .case-panel .pim-sku figcaption,
.case-detail--lighting .case-panel .pim-graph-kind,
.case-detail--lighting .case-panel .pim-graph-verb,
.case-detail--lighting .case-panel .pim-graph-note,
.case-detail--lighting .case-panel .pim-path-sep,
.case-detail--lighting .case-panel .pim-render figcaption {
  color: var(--lighting-muted);
}

.case-detail--lighting .case-panel .pim-optrec-rows dd,
.case-detail--lighting .case-panel .pim-rule-expr,
.case-detail--lighting .case-panel .pim-graph-title,
.case-detail--lighting .case-panel .pim-graph-target,
.case-detail--lighting .case-panel .pim-path-crumb,
.case-detail--lighting .case-panel .pim-render-lines,
.case-detail--lighting .case-panel .pim-render-body {
  color: var(--lighting-ink);
}

.case-detail--lighting .case-panel .pim-optrec-relation,
.case-detail--lighting .case-panel .pim-tier-name,
.case-detail--lighting .case-panel .pim-sku-token,
.case-detail--lighting .case-panel .pim-graph-glyph,
.case-detail--lighting .case-panel .pim-path-source,
.case-detail--lighting .case-panel .pim-path-crumbs .pim-path-crumb:last-child {
  color: var(--lighting-accent-dark);
}

.case-detail--lighting .case-panel .pim-optrec-relation {
  border-top-color: var(--lighting-line);
}

.case-detail--lighting .case-panel .pim-tier-items li,
.case-detail--lighting .case-panel .pim-graph-node,
.case-detail--lighting .case-panel .pim-graph-targets .pim-graph-target,
.case-detail--lighting .case-panel .pim-rule,
.case-detail--lighting .case-panel .pim-path {
  color: var(--lighting-ink);
  border-color: var(--lighting-line);
  background: var(--lighting-surface-alt);
}

.case-detail--lighting .case-panel .pim-tier:not(:last-child)::after,
.case-detail--lighting .case-panel .pim-graph-edge::before {
  background: var(--lighting-line-strong);
}

.case-detail--lighting .case-panel .pim-graph-edges {
  border-left-color: var(--lighting-line-strong);
}

/* IF / THEN / AND are operators, not semantic colour categories. */
.case-detail--lighting .case-panel .pim-rule-kw {
  color: var(--lighting-accent-dark);
}

.case-detail--lighting .case-panel .pim-rule-kw--then {
  color: var(--lighting-accent);
}

.case-detail--lighting .case-panel .pim-rule-kw--and {
  color: var(--lighting-muted);
}

.case-detail--lighting .case-panel .pim-sku-label {
  border-top-color: var(--lighting-line-strong);
}

.case-detail--lighting .case-panel .pim-sku-token {
  text-shadow: none;
}

.case-detail--lighting .case-panel .pim-path,
.case-detail--lighting .case-panel .pim-render,
.case-detail--lighting .case-panel .pim-graph-reverse {
  box-shadow: 0 8px 18px rgba(27, 42, 59, .05);
}

/* Alloy-family accents: these are grouping cues inside the otherwise uniform
   steel shell. They never recolour the editorial imagery or semantic copy. */
.case-detail--lighting .pim-tone--lilac { --lighting-group: #52677e; }
.case-detail--lighting .pim-tone--plum { --lighting-group: #6d6179; }
.case-detail--lighting .pim-tone--mint { --lighting-group: #3e6b64; }
.case-detail--lighting .pim-tone--sky { --lighting-group: #356b90; }
.case-detail--lighting .pim-tone--peach { --lighting-group: #7c604e; }
.case-detail--lighting .pim-tone--gold { --lighting-group: #76622f; }
.case-detail--lighting .pim-tone--aqua { --lighting-group: #356c72; }
.case-detail--lighting .pim-tone--sage { --lighting-group: #576f58; }
.case-detail--lighting .pim-tone--rose { --lighting-group: #805e6b; }

/* The SKU is the one place where the family grouping is most explicit. */
.case-detail--lighting .pim-sku-seg .pim-sku-token {
  color: var(--lighting-group, var(--lighting-accent-dark));
}

.case-detail--lighting .pim-sku-seg .pim-sku-label {
  border-top-color: color-mix(in srgb, var(--lighting-group, var(--lighting-accent)) 72%, var(--lighting-line));
}

/* Option records keep neutral cards and values; the family only marks the
   record edge and its compact code chip. */
.case-detail--lighting .pim-optrec {
  border-top-color: var(--lighting-group, var(--lighting-accent));
}

.case-detail--lighting .pim-optrec .pim-optrec-code {
  color: var(--lighting-group, var(--lighting-accent-dark));
  background: color-mix(in srgb, var(--lighting-group, var(--lighting-accent)) 11%, var(--lighting-surface-alt));
}

/* Tier descent uses the family only on its structural rail, name and
   connector; attribute chips remain neutral. */
.case-detail--lighting .pim-tier {
  border-left-color: var(--lighting-group, var(--lighting-accent));
}

.case-detail--lighting .pim-tier .pim-tier-name {
  color: var(--lighting-group, var(--lighting-accent-dark));
}

.case-detail--lighting .pim-tier:not(:last-child)::after {
  background: var(--lighting-group, var(--lighting-line-strong));
}

/* Relationship rows use family colour for the connector, glyph and outlines,
   while their node fills and relationship text stay steel-neutral. */
.case-detail--lighting .pim-graph-edge::before {
  background: var(--lighting-group, var(--lighting-accent));
}

.case-detail--lighting .pim-graph-edge .pim-graph-glyph {
  color: var(--lighting-group, var(--lighting-accent-dark));
}

.case-detail--lighting .pim-graph-edge .pim-graph-node {
  border-color: color-mix(in srgb, var(--lighting-group, var(--lighting-accent)) 48%, var(--lighting-line));
}

.case-detail--lighting .pim-graph-edge .pim-graph-targets .pim-graph-target {
  border-color: color-mix(in srgb, var(--lighting-group, var(--lighting-accent)) 38%, var(--lighting-line));
}

/* A classification path has one family rail and two labels, not a tinted
   breadcrumb surface. */
.case-detail--lighting .pim-path {
  border-left-color: var(--lighting-group, var(--lighting-accent));
}

.case-detail--lighting .pim-path .pim-path-source,
.case-detail--lighting .pim-path .pim-path-crumbs .pim-path-crumb:last-child {
  color: var(--lighting-group, var(--lighting-accent-dark));
}

.case-detail--lighting .pim-render {
  border-top-color: var(--lighting-group, var(--lighting-accent));
}

.case-detail--lighting .pim-render .pim-card-glyph {
  color: var(--lighting-group, var(--lighting-accent-dark));
}

/* Keep the Services contact anchor below the sticky navigation. */
.consult-contact { scroll-margin-top: 92px; }
