/* Andon page CSS, copied verbatim from pages/andon-system.php by
 * .scripts/spanish_andon/sync_andon_css.php. Do not edit here: edit the US
 * page, re-run that script, and bump ASSET_VER in intl/boot.php.
 *
 * The US page keeps these rules inline. They are pulled out into a file for
 * the Spanish sites because both locales share them, so one copy in one
 * place is what keeps them from drifting apart.
 */
	/* The non-US twin of anything that offers the trial. Present only on the first pageview of
	   a session, while the country is still unknown; custom.js reveals it and hides .show-us
	   the moment the lookup says the visitor is not in the US. */
	.hide-us{ display:none; }

	/* ---- Andon page-local visuals (px-) + reused andon/bed-exit components ---- */
	/* Hero: the interactive floor demo (self-sizes from inside the iframe) */
	.px-hero-demo{ max-width:1120px; margin:var(--sp-6) auto 0; }
	.px-hero-embed{ display:block; width:100%; min-height:520px; border:0; border-radius:var(--radius); background:#f4f6f9; box-shadow:0 24px 60px rgba(8,15,30,.45); }
	.px-hero-actions{ display:flex; flex-wrap:wrap; gap:var(--sp-3); justify-content:center; margin-top:var(--sp-6); }

	/* Storyboard: main pain point */
	.storyboard-minimal { background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-lg); overflow:hidden; box-shadow:var(--shadow-sm); }
	.storyboard-panels { display:grid; grid-template-columns:repeat(4, 1fr); }
	.storyboard-panel { padding:2rem 1.5rem; border-right:1px solid var(--border); text-align:center; position:relative; }
	.storyboard-panel:last-child { border-right:none; }
	.panel-num { position:absolute; top:.75rem; left:.75rem; width:24px; height:24px; background:var(--accent); color:var(--accent-ink); font-size:.75rem; font-weight:700; border-radius:50%; display:flex; align-items:center; justify-content:center; }
	.storyboard-panel:first-child .panel-num { background:var(--ink); color:var(--accent-ink); }
	.panel-time { font-size:1.5rem; font-weight:800; color:var(--accent); margin-bottom:1rem; font-family:var(--font-mono); }
	.storyboard-panel:first-child .panel-time { color:var(--ink); }
	.panel-icon { font-size:2rem; margin-bottom:.75rem; }
	.panel-text { font-size:1rem; color:var(--ink-soft); line-height:1.5; margin-bottom:0; }
	.panel-bubble { background:var(--bg-subtle); border-radius:var(--radius); padding:.75rem 1rem; position:relative; margin-top:.75rem; font-style:italic; font-size:1rem; color:var(--ink); }
	.panel-bubble::before { content:''; position:absolute; top:-8px; left:50%; transform:translateX(-50%); border-left:8px solid transparent; border-right:8px solid transparent; border-bottom:8px solid var(--bg-subtle); }
	.storyboard-conclusion { border-top:3px solid var(--accent); padding:2rem; text-align:center; }
	.storyboard-conclusion :is(h3, h4) { color:var(--ink-soft); font-size:1rem; font-weight:500; margin-bottom:.5rem; }
	.storyboard-cost { display:flex; flex-direction:column; gap:.25rem; }
	.storyboard-cost .cost-time { font-size:1.5rem; font-weight:600; color:var(--ink); }
	.storyboard-cost .cost-money { font-size:2rem; font-weight:800; color:var(--accent); }

	/* "One board" whole-plant dashboard iframe (same treatment as nurse-call / bed-exit) */
	.px-board{ max-width:1000px; margin:0 auto; }
	.px-board-embed{ display:block; width:100%; min-height:460px; border:0; border-radius:16px; background:transparent; }

	/* The same board on three screens at once. Ported from the medical page's
	   .px-device cluster and renamed, because .px-board here already belongs to
	   the live embed above it. Deliberately static: the live board is directly
	   overhead, so all this has to carry is that it is one board on as many
	   screens as you own, not a second demo competing with the first. */
	.px-screens__lead{ max-width:680px; margin:var(--sp-7) auto 0; text-align:center; color:var(--ink-soft); }
	.px-screens{ display:flex; flex-wrap:wrap; gap:var(--sp-6); align-items:flex-end; justify-content:center; margin-top:var(--sp-5); }
	.px-dev{ --bezel:#141a2b; --stand:#c4ccd6; --stand2:#9aa4b0; text-align:center; flex:0 0 auto; }
	.px-dev__screen{ background:var(--band-bg); overflow:hidden; box-shadow:var(--shadow-lg); }
	.px-dev--tv  .px-dev__screen{ width:344px; height:202px; font-size:13.5px; border:9px solid #0a0e18; border-radius:8px; }
	.px-dev--mon .px-dev__screen{ width:300px; height:180px; font-size:12.5px; border:9px solid var(--bezel); border-radius:12px; }
	.px-dev--lap .px-dev__screen{ width:284px; height:170px; font-size:12px; border:8px solid var(--bezel); border-bottom:none; border-radius:10px 10px 0 0; }
	.px-dev__mount{ width:36px; height:16px; background:var(--stand2); border-radius:0 0 4px 4px; margin:0 auto; }
	.px-dev__neck{ width:52px; height:24px; background:linear-gradient(var(--stand),var(--stand2)); margin:0 auto; }
	.px-dev__foot{ width:152px; height:11px; background:var(--stand2); border-radius:6px; margin:0 auto; }
	.px-dev__base{ height:12px; width:306px; max-width:100%; background:linear-gradient(var(--stand),var(--stand2)); border-radius:0 0 12px 12px; position:relative; margin:0 auto; }
	.px-dev__base::before{ content:""; position:absolute; top:0; left:50%; transform:translateX(-50%); width:64px; height:5px; background:var(--stand2); border-radius:0 0 6px 6px; }
	.px-dev__label{ font-size:var(--fs-small); font-weight:700; color:var(--ink); margin-top:var(--sp-3); line-height:1.25; }
	.px-dev__label span{ display:block; font-weight:600; color:var(--ink-soft); }
	/* The floor board at a sixth of the size. Colours, the dark bar, the segmented
	   view tabs and the counts strip are lifted from andon-floor.html so these
	   read as the board the reader just watched rather than a second product.
	   Six stations instead of twelve: at this width twelve tiles put the station
	   names below the size anyone can read, and six still says "map of the plant".
	   Sized in em so one set of rules serves all three screens. */
	.px-mini{ width:100%; height:100%; background:#f4f6f9; font-family:var(--font-body); text-align:left; display:flex; flex-direction:column; }
	.px-mini__bar{ display:flex; align-items:center; gap:.6em; background:#1c222c; padding:.42em .55em; flex:0 0 auto; }
	.px-mini__seg{ display:inline-flex; gap:.15em; padding:.16em; border-radius:.5em; background:rgba(255,255,255,.09); }
	.px-mini__seg b{ font-size:.62em; font-weight:700; color:#96a2b1; padding:.34em .7em; border-radius:.34em; white-space:nowrap; }
	.px-mini__seg b.on{ background:#fff; color:#151b24; }
	.px-mini__clock{ margin-left:auto; color:#e7ecf2; font-size:.62em; font-weight:800; letter-spacing:.02em; }
	.px-mini__panel{ background:#fff; border:1px solid #e3e8ef; border-radius:.5em; margin:.5em; overflow:hidden; flex:1 1 auto; display:flex; flex-direction:column; }
	.px-mini__hd{ display:flex; align-items:center; gap:.85em; padding:.34em .6em; background:#f7f9fb; border-bottom:1px solid #e3e8ef; flex:0 0 auto; }
	.px-mini__cnt{ display:flex; align-items:center; gap:.3em; font-size:.58em; font-weight:700; color:#5c6773; }
	.px-mini__cnt i{ width:.5em; height:.5em; border-radius:50%; font-style:normal; }
	.px-mini__cnt b{ color:#10151c; font-weight:800; }
	.px-mini__cnt--run i{ background:#75c449; }
	.px-mini__cnt--wait i{ background:#ec5b51; }
	.px-mini__cnt--onit i{ background:#f0b024; }
	.px-mini__grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:.34em; padding:.42em; flex:1 1 auto; }
	.px-mini__tile{ border:1px solid #75c449; background:#a9dd80; color:#33581a; border-radius:.36em; padding:.2em .25em;
		display:flex; flex-direction:column; justify-content:center; align-items:center; text-align:center; overflow:hidden; }
	.px-mini__tile b{ font-size:.66em; font-weight:800; line-height:1.1; }
	.px-mini__tile s{ font-size:.55em; font-weight:700; opacity:.82; text-decoration:none; line-height:1.15; margin-top:.15em; }
	.px-mini__tile u{ font-size:.6em; font-weight:800; text-decoration:none; letter-spacing:.02em; margin-top:.1em; }
	.px-mini__tile--wait{ background:#f79a92; border-color:#ec5b51; color:#6e1a14; }
	.px-mini__tile--onit{ background:#fbd884; border-color:#f0b024; color:#6b4a06; }

	/* Pickup by text. Two threads side by side, because the point is what the
	   second person sees: a claim that arrives on one phone only is not a claim
	   the reader can watch anybody make. */
	/* The trigger sits in the kit row, in the slot every other component uses for
	   its Specifications fold, so it is where a reader of that row already looks.
	   Same mono treatment for the same reason, with the chevron turned sideways
	   because this one opens something rather than expanding in place. */
	button.dx-kit__thumb{ padding:0; }

	/* The one fold on the page that carries a picture: the repeater under the call
	   button. Half-size thumb, so the row it sits inside still reads as the button's. */
	.dx-fold__aside{ display:flex; gap:var(--sp-3); align-items:flex-start; margin-top:var(--sp-3); }
	.dx-fold__aside .dx-kit__thumb{ width:72px; height:72px; }
	.dx-fold__aside p{ margin:0; font-size:13px; line-height:1.6; color:var(--ink-soft); }
	.px-open{ display:inline-flex; align-items:center; gap:7px; margin-top:var(--sp-3); padding:0; border:0; background:none; cursor:pointer;
		font-family:var(--font-mono); font-size:11px; letter-spacing:.07em; text-transform:uppercase; color:var(--accent); }
	.px-open::after{ content:''; width:6px; height:6px; border-right:1.5px solid currentColor; border-top:1.5px solid currentColor; transform:rotate(45deg); }
	.px-open:hover{ text-decoration:underline; }

	/* A modal rather than a fold, because the optional panel leaves about 250px
	   next to the thumbnail and the two handsets need roughly 490 to sit side by
	   side. Styled to match .cs-modal from the shared case-studies component, so
	   the two popups on this page read as the same object; native <dialog> rather
	   than a copy of that component's script, since the browser supplies the
	   backdrop, the focus trap and Escape. */
	/* 88dvh, not 88vh. A fixed element sizes against the large viewport on a
	   phone -- the one that pretends the URL bar is hidden -- so 88vh of it
	   could be taller than the screen and push the top of the dialog, where
	   the close button is, up behind the browser chrome. Browsers without dvh
	   read the vh line above and behave as before. */
	.px-modal{ position:fixed; inset:0; margin:auto; width:calc(100% - 40px); max-width:640px; max-height:88vh; max-height:88dvh; overflow:hidden;
		padding:0; border:1px solid var(--border); border-radius:var(--radius); background:var(--surface); color:var(--ink); }
	.px-modal::backdrop{ background:rgba(15,23,42,.55); }
	/* Inside the scroll box (not on the dialog): absolute on the dialog sat on
	   the Windows scrollbar. Sticky + margin-left:auto keeps it in the content
	   column, left of the track, and pinned while you read. Negative bottom
	   margin collapses the line it would reserve so the title shares the top. */
	.px-modal__x{ position:sticky; top:8px; display:flex; align-items:center; justify-content:center;
		width:40px; height:40px; margin:0 2px -36px auto; border:1px solid var(--border);
		background:var(--bg-subtle); font-size:22px; line-height:1; color:var(--ink); cursor:pointer;
		border-radius:var(--radius-sm); z-index:3; }
	.px-modal__x:hover,.px-modal__x:focus-visible{ background:var(--ink); border-color:var(--ink); color:#fff; }
	/* scrollbar-gutter so an overlay scrollbar (Chrome) cannot paint over the
	   chip: without it the chip is in the client box and the track still lands
	   on top of it. */
	.px-modal__in{ position:relative; max-height:88vh; max-height:88dvh; overflow-y:auto;
		padding:16px 24px 24px; scrollbar-gutter:stable; }
	.px-modal__t{ margin:0; padding-right:48px; font-size:var(--fs-h4); }
	body.px-lock{ overflow:hidden; }
	.px-sms__lead{ margin:var(--sp-3) 0 0; color:var(--ink); font-size:var(--fs-small); }
	.px-sms{ display:flex; flex-wrap:wrap; gap:var(--sp-6) var(--sp-8); justify-content:center; align-items:flex-start; margin-top:var(--sp-6); }
	.px-sms__unit{ flex:0 0 auto; width:214px; }

	/* Whose phone this is, above it rather than under it. Underneath, the reader
	   met the conversation before they met the person, and two handsets in a row
	   read as one handset twice: a sequence of events on a single phone instead
	   of two people getting the same call at the same moment. The avatars carry
	   most of that load, so they are two clearly different colours. */
	.px-sms__who{ display:flex; align-items:center; gap:var(--sp-3); text-align:left; margin-bottom:var(--sp-4); }
	.px-sms__av{ flex:0 0 auto; width:34px; height:34px; border-radius:50%; display:flex; align-items:center; justify-content:center;
		font-size:12px; font-weight:800; color:#fff; letter-spacing:.03em; }
	.px-sms__av--a{ background:var(--accent); }
	.px-sms__av--b{ background:#3d4a5c; }
	.px-sms__av--c{ background:#2f6f8f; }
	.px-sms__who b{ display:block; font-size:var(--fs-small); font-weight:800; color:var(--ink); line-height:1.2; }
	.px-sms__who i{ display:block; font-style:normal; font-size:var(--fs-small); font-weight:600; color:var(--ink-soft); line-height:1.3; }

	/* The handset. The previous frame was a rounded card at roughly 3:4, which is
	   a tablet at best. What makes it read as a phone is the 1:2 screen, a bezel
	   thick enough to see on all four sides, side buttons breaking the outline,
	   and the two pieces of chrome every phone has and nothing else does: a
	   status bar and a home indicator. Screen height is fixed rather than driven
	   by its content, so both handsets are the same object even though one is
	   showing a locked screen and the other a list. */
	.px-sms__frame{ position:relative; display:flex; flex-direction:column; background:#12161c; border-radius:34px; padding:9px;
		box-shadow:0 18px 40px rgba(8,15,30,.3); }
	.px-sms__frame::before,.px-sms__frame::after{ content:""; position:absolute; background:#12161c; border-radius:0 2px 2px 0; }
	.px-sms__frame::before{ left:-3px; top:86px; width:3px; height:54px; border-radius:2px 0 0 2px; }
	.px-sms__frame::after{ right:-3px; top:100px; width:3px; height:38px; }
	/* 432 rather than 392: three call cards, a tab bar and the two pieces of chrome
	   need 432, and at 392 the tab bar was the thing that got clipped — which is the
	   one detail saying this is the whole app. It also puts the screen closer to a
	   real handset's 1:2.15 than the shorter box was. */
	.px-sms__screen{ position:relative; height:432px; display:flex; flex-direction:column; background:#fff; border-radius:26px; overflow:hidden; }
	.px-sms__notch{ position:absolute; top:7px; left:50%; transform:translateX(-50%); width:62px; height:17px; background:#12161c; border-radius:10px; z-index:3; }
	.px-sms__status{ display:flex; align-items:center; justify-content:space-between; padding:9px 13px 4px; flex:0 0 auto;
		font-size:9.5px; font-weight:800; color:#10151c; font-variant-numeric:tabular-nums; }
	.px-sms__ico{ display:block; width:44px; height:10px; }
	.px-sms__bar{ flex:0 0 auto; width:92px; height:4px; border-radius:3px; background:#10151c; opacity:.8; margin:6px auto 7px; }
	/* Full ink rather than the body gray these read as on an open page: over a
	   dimmed backdrop the same value reads a shade weaker than it does in a
	   section, and this is the argument for the phone tier, not a caption. */
	.px-sms__note{ margin:var(--sp-6) 0 0; color:var(--ink); font-size:var(--fs-small); }
	.px-sms__note + .px-sms__note{ margin-top:var(--sp-4); }

	/* The app screens live in the same handset as the threads above, because the
	   frame is the part that says "phone" and it should say it the same way
	   twice. What changes is the content: a locked screen with the notification
	   on it, and the open-call list that notification opens. Cards with a clock
	   on each one rather than chat bubbles — a list of calls, each with its own
	   wait and its own Take, is the entire difference from a text message, so it
	   cannot be drawn as a text message. */
	/* The whole screen goes dark, not just the area under the status bar: the clock
	   and the signal icons are part of a locked phone and they have to sit on the
	   wallpaper. Top of the gradient stays lighter than the notch so the notch and
	   the status bar still read as chrome instead of dissolving into it. */
	.px-sms__screen--lock{ background:#2b3a4c; }
	.px-sms__screen--lock .px-sms__bar{ background:#fff; opacity:.45; }
	.px-app__lock{ flex:1 1 auto; display:flex; flex-direction:column; gap:7px; padding:0 8px;
		background:linear-gradient(168deg,#2b3a4c,#0d1319 76%); }
	.px-app__clock{ padding:24px 0 12px; text-align:center; color:#fff; }
	.px-app__clock b{ display:block; font-size:36px; font-weight:700; line-height:1; letter-spacing:-.02em; font-variant-numeric:tabular-nums; }
	.px-app__clock span{ display:block; margin-top:3px; font-size:9.5px; font-weight:600; color:rgba(255,255,255,.72); }
	.px-app__push{ background:rgba(255,255,255,.94); border-radius:13px; padding:7px 9px; text-align:left; }
	.px-app__push em{ display:flex; align-items:center; gap:5px; font-style:normal; font-size:8.5px; font-weight:800;
		letter-spacing:.05em; text-transform:uppercase; color:#7b8593; }
	.px-app__push em::before{ content:""; flex:0 0 auto; width:11px; height:11px; border-radius:3px; background:var(--accent); }
	.px-app__push em span{ margin-left:auto; font-weight:600; letter-spacing:0; text-transform:none; }
	.px-app__push strong{ display:block; margin-top:3px; font-size:11.5px; font-weight:800; color:#10151c; line-height:1.25; }
	.px-app__push i{ display:block; font-style:normal; margin-top:1px; font-size:10.5px; line-height:1.35; color:#3b4553; }
	.px-app__head{ display:flex; align-items:baseline; justify-content:space-between; gap:var(--sp-2); flex:0 0 auto;
		padding:4px 11px 7px; border-bottom:1px solid #e3e8ef; text-align:left; }
	.px-app__head b{ font-size:11.5px; font-weight:800; color:#10151c; }
	.px-app__head span{ font-size:9px; font-weight:700; color:var(--accent); }
	.px-app__list{ flex:1 1 auto; padding:8px; display:flex; flex-direction:column; gap:7px; text-align:left; }
	.px-app__call{ border:1px solid #e0e6ee; border-radius:11px; padding:7px 8px; }
	.px-app__call b{ display:block; font-size:11px; font-weight:800; color:#10151c; }
	.px-app__call i{ display:block; font-style:normal; margin-top:1px; font-size:9.5px; font-weight:600; color:#7b8593; }
	/* The wait is neutral and only the word "late" carries the accent. All of it in
	   the accent put three reds in one card next to a red Take button, which read
	   as an alarm going off rather than a list of calls with one of them overdue. */
	.px-app__wait{ display:block; margin-top:4px; font-size:9px; font-weight:800; color:#5b6675; font-variant-numeric:tabular-nums; }
	.px-app__wait em{ font-style:normal; color:#a83a14; }
	.px-app__take,.px-app__held{ display:block; margin-top:5px; border-radius:8px; padding:5px 0; text-align:center;
		font-size:10px; font-weight:800; letter-spacing:.02em; }
	.px-app__take{ background:var(--accent); color:#fff; }
	.px-app__held{ background:#eef1f5; color:#5b6675; }

	/* The tab bar is the cheapest way to say "this is the whole thing, not a call
	   list": three words at the bottom of the screen do what a third handset or
	   another paragraph would have to. Calls is the active one because that is the
	   screen the notification opens to. */
	.px-app__tabs{ display:flex; flex:0 0 auto; border-top:1px solid #e3e8ef; }
	.px-app__tabs span{ flex:1 1 0; padding:6px 0 4px; text-align:center; font-size:8.5px; font-weight:800;
		letter-spacing:.02em; color:#a3abb6; }
	.px-app__tabs span::before{ content:""; display:block; width:12px; height:12px; margin:0 auto 3px;
		border-radius:3px; background:currentColor; opacity:.4; }
	.px-app__tabs .is-on{ color:var(--accent); }
	.px-app__tabs .is-on::before{ opacity:1; }

	/* The three screens stay on one row all the way down, instead of stacking.

	   Stacked they cost 808px of scrolling on a phone to make a point the
	   sentence above them makes in a line -- the same board, on three screens,
	   off hardware you already own -- and that point is "all three at once",
	   which a reader scrolling past one board at a time never sees. In a row it
	   costs 108px.

	   The row holds from 0 to 1061px because that is where the drawn sizes stop
	   fitting: 344 + 300 + 306 of device plus two 32px gaps needs 1014px, and
	   the container is the viewport less 48px of padding. Above it the rules at
	   the top of this file take over unchanged.

	   One number per device drives everything. Inside .px-mini every size is
	   already em, so the board scales off the screen's font-size for free; the
	   screen box and the stands are written in em here for the same reason,
	   against the same drawn pixels the desktop uses (344/13.5 = 25.481em, and
	   so on down). The three font-sizes shrink on one shared ratio -- container
	   over 1014 -- so the row fills the container exactly at any width, the gaps
	   shrink with it, the 344:300:284 ranking survives, and at 1062 the ratio
	   reaches 1 and the em values land back on the drawn pixels. That last part
	   is what removes the cliff: nothing jumps at the breakpoint.

	   Labels are the exception. They are text a reader reads, so they ramp on
	   their own from 10px to the 14px above the breakpoint rather than riding a
	   ratio down to 4px with the hardware.

	   The type inside the boards does ride it down, to about 4px on a phone. It
	   is not meant to be read there. The readable board is live, full size and
	   moving a few hundred pixels up this same section, and by here it has been
	   read; what has to survive is that there are three, that they are a TV, a
	   monitor and a laptop, and where each one hangs. On a 2x or 3x handset the
	   smudge is at least a sharp smudge. */
	@media (max-width:1061px){
		.px-screens{ flex-wrap:nowrap; gap:min(32px, calc(3.1558vw - 1.51px)); }
		.px-dev{ flex:0 0 auto; min-width:0; }
		/* Each device states its width instead of taking it from its widest child.
		   Left to the content it was as wide as whichever was wider, the hardware
		   or the label -- and on the Spanish page the labels are wider than the
		   hardware they sit under ("Oficina de mantenimiento" over an 87px
		   laptop), which pushed the row 5px off a 360px screen. Stated here, the
		   label wraps inside the device and the row is exactly the three widths
		   plus the gaps. Same numbers the screens use, except the laptop, whose
		   base flares 25.5em wide against a 23.667em screen. */
		.px-dev--tv { width:25.481em; font-size:min(13.5px, calc(1.3314vw - 0.64px)); }
		.px-dev--mon{ width:24em;     font-size:min(12.5px, calc(1.2327vw - 0.59px)); }
		.px-dev--lap{ width:25.5em;   font-size:min(12px,   calc(1.1834vw - 0.57px)); }
		/* Same two classes as the rules above, so these win on source order and
		   the screen picks up the ratio set on its device. */
		.px-dev--tv  .px-dev__screen,
		.px-dev--mon .px-dev__screen,
		.px-dev--lap .px-dev__screen{ font-size:inherit; height:auto; }
		/* aspect-ratio rather than a height, because the width is now an em
		   value and the height has to follow it. */
		.px-dev--tv  .px-dev__screen{ width:25.481em; aspect-ratio:344/202; border-width:.667em; border-radius:.593em; }
		.px-dev--mon .px-dev__screen{ width:24em;     aspect-ratio:300/180; border-width:.72em;  border-radius:.96em; }
		.px-dev--lap .px-dev__screen{ width:23.667em; aspect-ratio:284/170; border-width:.667em; border-radius:.833em .833em 0 0; }
		.px-dev__mount{ width:2.667em; height:1.185em; border-radius:0 0 .3em .3em; }
		.px-dev__neck{ width:4.16em; height:1.92em; }
		.px-dev__foot{ width:12.16em; height:.88em; border-radius:.48em; }
		.px-dev__base{ width:25.5em; max-width:none; height:1em; border-radius:0 0 .96em .96em; }
		.px-dev__base::before{ width:5.333em; height:.417em; border-radius:0 0 .5em .5em; }
		/* The gap over the label ramps too, from 7px to the 12px of --sp-3 above
		   the breakpoint. Left at 7 it was the one thing that still stepped at
		   1062, and 5px of block height is not worth an inconsistency. */
		.px-dev__label{ font-size:clamp(10px, calc(0.5952vw + 7.68px), 14px); margin-top:clamp(7px, calc(0.744vw + 4.1px), 12px); overflow-wrap:break-word; }
		.px-dev__label span{ font-size:clamp(9px, calc(0.744vw + 6.1px), 14px); }
	}
	@media (max-width:560px){
		/* A 48px gutter each side leaves the 214px handset almost no room on a
		   350px modal. Same trim .cs-modal takes at this width. */
		.px-modal__in{ padding:14px 16px 22px; }
		.px-modal__x{ top:6px; width:36px; height:36px; font-size:20px; }
	}

	/* Board legend. A caption, not a feature list: it annotates the screen above
	   it, so it stays at caption weight and wraps as one flowing strip. */
	.px-legend{ display:flex; flex-wrap:wrap; justify-content:center; gap:6px var(--sp-5); max-width:900px; margin:var(--sp-4) auto 0; }
	/* Block, not inline-flex: a bare text node beside a <b> would become two
	   flex items and the label could break away from its own sentence. */
	.px-legend__i{ display:block; position:relative; padding-left:16px; max-width:100%; font-size:.82rem; color:var(--ink-faint); line-height:1.45; }
	.px-legend__i b{ color:var(--ink); font-weight:700; }
	.px-legend__d{ position:absolute; left:0; top:.42em; width:9px; height:9px; border-radius:50%; }
	/* the board's own three colours, and the hero demo's: green running, red
	   stopped and waiting, yellow someone is on it. Escalation is not a fourth
	   colour because the floor does not have one — it is red, deeper. */
	.px-legend__d--run { background:#75c449; }
	.px-legend__d--wait{ background:#ec5b51; }
	.px-legend__d--onit{ background:#f0b024; }
	@media (max-width:720px){ .px-legend{ justify-content:flex-start; gap:8px; flex-direction:column; } }

	/* The CTA moved inside the padded ROI box, and its label does not fit a
	   phone-width column while nowrap holds. Let it wrap there. */
	@media (max-width:720px){
		.dx-price-roi{ padding-left:var(--sp-5); padding-right:var(--sp-5); }
		.dx-price-roi .ds-btn{ white-space:normal; }
	}

	/* A quiet aside: a note about how to read the thing above it, not a claim
	   of its own, so it gets a rule and a tint rather than card furniture. */
	.px-aside{ max-width:860px; margin:var(--sp-7) auto 0; border-left:3px solid var(--border-strong, var(--border)); background:var(--bg-subtle); border-radius:0 var(--radius) var(--radius) 0; padding:var(--sp-4) var(--sp-5); }
	.px-aside p{ margin:0; color:var(--ink-soft); }
	.px-aside strong{ color:var(--ink); }

	/* Price tiers, matching the ones in files/presentation.php off the same
	   catalog. A split bar labeled "backbone" and "floor" used to sit at the
	   bottom of each card, drawing the fixed share shrinking left to right. It
	   was an accurate picture of an argument nobody asked to see in chart form,
	   and it required the reader to learn two invented words before it meant
	   anything. The same point is now simply stated underneath, which is how
	   the document has always done it. */
	/* The flag straddles the top border instead of sitting in the card, so all
	   three tiers start their content at the same height and the row reads as
	   one comparison rather than three unaligned boxes. */
	.px-tier--flag{ position:relative; }
	.px-tier__flag{
		position:absolute; top:0; left:50%; transform:translate(-50%,-50%);
		white-space:nowrap; background:var(--accent); color:var(--accent-ink,#fff);
		font-size:.7rem; font-weight:800; letter-spacing:.06em; text-transform:uppercase;
		padding:5px 14px; border-radius:var(--radius-pill,999px);
	}
	.px-tier__scale{ font-size:.72rem; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-faint); font-weight:800; }
	/* margin-top:auto pins this to the bottom, so the three cards align on it. */
	/* The rule under the price needs matching air on both sides, and it can't
	   come from this block: margin-top:auto pins the include line to the foot of
	   the card so the three align on it, and auto overrides any top margin set
	   with it. (This rule used to open "margin:var(--sp-5) 0 0", which auto
	   silently discarded, leaving the rule flush against "one-time" with 16px
	   under it and nothing over it.) So the gap is a margin-bottom on the amount
	   above, which auto can't touch. files/presentation.php gets the same result
	   with .oneoff's margin-bottom against .incl's padding-top. */
	.ds-price__amount{ margin-bottom:var(--sp-4); }
	.px-tier__incl{ margin:0; margin-top:auto; padding-top:var(--sp-4); border-top:1px solid var(--border); font-size:var(--fs-small); color:var(--ink-soft); }

	/* Pareto, drawn in CSS from the real numbers in the customer's own report.
	   Horizontal bars because the station names are long and this has to stay
	   readable on a phone, which the original chart image never was. */
	.px-par{ background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); padding:var(--sp-6); }
	.px-par__hd{ display:flex; align-items:baseline; justify-content:space-between; gap:var(--sp-3); margin-bottom:var(--sp-2); }
	.px-par__hd :is(h3, h4){ margin:0; }
	.px-par__unit{ font-size:.78rem; color:var(--ink-faint); white-space:nowrap; }
	.px-par__sub{ font-size:.9rem; color:var(--ink-soft); margin:0 0 var(--sp-5); }
	.px-par__rows{ display:flex; flex-direction:column; gap:7px; }
	.px-par__row{ display:grid; grid-template-columns:minmax(96px,124px) 1fr 46px; align-items:center; gap:10px; }
	.px-par__lbl{ font-size:.82rem; color:var(--ink-soft); line-height:1.25; }
	.px-par__track{ background:var(--bg-subtle); border-radius:5px; height:19px; overflow:hidden; }
	.px-par__bar{ display:block; height:100%; border-radius:5px; background:var(--border-strong); }
	.px-par__val{ font-size:.82rem; font-weight:700; text-align:right; color:var(--ink-soft); font-variant-numeric:tabular-nums; }
	.px-par__row.is-top .px-par__lbl,
	.px-par__row.is-top .px-par__val{ color:var(--ink); }
	.px-par__row.is-top .px-par__bar{ background:var(--accent); }
	/* The Pareto break. A CI engineer reads the gap between the bars and the tail
	   before he reads any caption, so the line is where the finding lands. */
	.px-par__cut{ display:flex; align-items:center; gap:10px; margin:8px 0 1px; }
	.px-par__cut b{ font-size:.7rem; letter-spacing:.06em; text-transform:uppercase; font-weight:800; color:var(--accent); white-space:nowrap; }
	.px-par__cut i{ flex:1 1 auto; height:0; border-top:1px dashed var(--accent); opacity:.5; }
	.px-par__row.is-rest{ margin-top:3px; padding-top:7px; border-top:1px dashed var(--border); }
	.px-par__row.is-rest .px-par__lbl{ font-style:italic; color:var(--ink-faint); }
	.px-par__row.is-rest .px-par__val{ color:var(--ink-faint); }
	.px-par__note{ margin:var(--sp-5) 0 0; padding-top:var(--sp-4); border-top:1px solid var(--border); font-size:.88rem; color:var(--ink-soft); }
	.px-par__note strong{ color:var(--ink); }
	/* Sits above both charts because it applies to both, and because what these
	   bars are made of is the whole reason they aren't another downtime report.
	   Surface rather than the .px-aside recipe: this section is already tinted,
	   so bg-subtle on bg-subtle would disappear. */
	.px-par__unitline{ max-width:860px; margin:0 auto var(--sp-5); background:var(--surface); border:1px solid var(--border); border-left:3px solid var(--accent); border-radius:0 var(--radius) var(--radius) 0; padding:var(--sp-4) var(--sp-5); }
	.px-par__unitline p{ margin:0; font-size:.95rem; color:var(--ink-soft); }
	.px-par__unitline strong{ color:var(--ink); }
	/* Everything above it is one plant in Ohio, which a reader takes at arm's
	   length. This is the sentence that turns the section to him, so it is plain
	   centred type rather than a second box under the one above the charts. */
	.px-par__turn{ max-width:760px; margin:var(--sp-6) auto 0; text-align:center; font-size:1.05rem; color:var(--ink-soft); }
	.px-par__turn strong{ color:var(--ink); }
	@media (max-width: 520px){ .px-par{ padding:var(--sp-4); } .px-par__row{ grid-template-columns:minmax(78px,96px) 1fr 40px; gap:7px; } .px-par__lbl{ font-size:.76rem; } }

	/* Inside a .dx-pain body: the attribution under a quote, and the arithmetic box */
	.px-quote-src { font-size:.875rem; color:var(--ink-faint); margin:.5rem 0 0; padding-left:var(--sp-4); }
	.px-pain-math { background:var(--bg-subtle); border:1px solid var(--border); border-radius:var(--radius-sm); padding:1rem; margin-top:var(--sp-4); }
	.px-pain-math p { margin-bottom:.5rem; font-size:.95rem; color:var(--ink-soft); }
	.px-pain-math p:last-child { margin-bottom:0; }

	/* Dark stat band (bed-exit px-statband) */
	.px-statband{ position:relative; overflow:hidden; }
	.px-statband__glow{ position:absolute; inset:0; pointer-events:none; background:radial-gradient(58% 120% at 50% -12%, rgba(222,29,35,.18), transparent 60%); }
	.px-statband > .ds-container{ position:relative; }
	/* Two, not three. The third stat here was "48 h to your first wait-time
	   report", which is a claim about DATA sitting between two claims about
	   LOSS, so in this position it read as a promise that something improves in
	   two days. It still runs in the trial section, where the words around it
	   say plainly that what arrives is numbers. */
	.px-stats{ display:grid; grid-template-columns:repeat(2,1fr); gap:var(--sp-4); max-width:680px; margin:var(--sp-7) auto 0; }
	.px-stat{ text-align:center; padding:var(--sp-6) var(--sp-4); background:rgba(255,255,255,.04); border:1px solid rgba(255,255,255,.09); border-radius:var(--radius-lg); transition:transform .18s ease, background .18s ease, border-color .18s ease; }
	.px-stat:hover{ transform:translateY(-3px); background:rgba(255,255,255,.06); border-color:rgba(255,255,255,.16); }
	.px-stat__n{ font-family:var(--font-head); font-weight:800; line-height:1; letter-spacing:-0.02em; color:#fff; font-size:clamp(2.4rem, 1.6rem + 3vw, 3.4rem); }
	.px-stat--focal .px-stat__n{ color:#ff4b51; }
	.px-stat__l{ color:var(--band-ink-soft); font-size:0.92rem; margin-top:var(--sp-3); }
	.px-stat__src{ color:var(--band-ink-soft); opacity:.7; font-size:0.72rem; margin-top:var(--sp-2); }
	.px-stats .px-stat:nth-child(2){ transition-delay:.08s; }
	.px-stats .px-stat:nth-child(3){ transition-delay:.16s; }
	.px-reveal{ opacity:0; transform:translateY(16px); transition:opacity .55s ease, transform .55s ease; }
	.px-reveal.is-in{ opacity:1; transform:none; }
	@media (prefers-reduced-motion:reduce){ .px-reveal{ opacity:1; transform:none; transition:none; } }

	/* Comparison table (bed-exit px-cmp) */
	.px-cmp-wrap{ overflow-x:auto; }
	.px-cmp{ width:100%; border-collapse:separate; border-spacing:0; background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); overflow:hidden; min-width:640px; }
	.px-cmp th, .px-cmp td{ padding:var(--sp-3) var(--sp-4); text-align:center; border-bottom:1px solid var(--border); font-size:var(--fs-small); vertical-align:middle; }
	.px-cmp tbody tr:last-child td{ border-bottom:0; }
	.px-cmp thead th{ font-weight:800; color:var(--ink); }
	.px-cmp td:first-child, .px-cmp th:first-child{ text-align:left; font-weight:700; color:var(--ink); }
	.px-cmp .px-us{ background:var(--bg-subtle); }
	.px-cmp thead .px-us{ background:var(--accent); color:#fff; }
	.px-yes{ color:#1c8f4e; font-weight:800; }
	.px-no{ color:var(--ink-faint); font-weight:700; }

	@media (max-width: 767px) {
		.storyboard-panels { grid-template-columns:repeat(2, 1fr); }
		.storyboard-panel { padding:1.5rem 1rem; }
		.storyboard-panel:nth-child(3), .storyboard-panel:nth-child(4) { border-top:1px solid var(--border); }
		.panel-icon { font-size:1.75rem; margin-bottom:.5rem; }
		.storyboard-conclusion { padding:1.5rem 1rem; }
		.storyboard-cost .cost-time { font-size:1.1rem; }
		.storyboard-cost .cost-money { font-size:1.5rem; }
		/* The cost chip can't wrap, so on a phone it squeezes the title into four lines.
		   Drop it onto its own row under the title instead. */
		.dx-pain summary { padding:var(--sp-4); gap:var(--sp-3); flex-wrap:wrap; }
		.dx-pain__ic { width:32px; height:32px; flex-basis:32px; font-size:1rem; }
		.dx-pain__t { flex:1 1 0; min-width:0; }
		/* flex-basis:100% is what forces the break, so the pill would stretch edge to edge.
		   Drop the pill and let it read as a caption under the title. */
		.dx-pain__cost { order:4; flex-basis:100%; margin-left:calc(32px + var(--sp-3)); padding:0; background:none; font-size:.75rem; }
		.px-stats{ grid-template-columns:1fr; }
	}

	/* Print: a champion needs something to put in front of a plant manager, and there is no
	   PDF to download by design. Ctrl-P should produce it. Drops what cannot print (the
	   interactive demo, carousel clones, buttons that open a scheduler), flattens the dark
	   band so it stays readable on paper, and forces every accordion open. */
	@media print {
		.notification, .dx-footer, footer, .px-hero-demo, .px-hero-actions, .px-board,
		.dx-syshero__note,
		.ds-cta, .ds-btn, .cs-modal-root, .cs-modal-sources { display: none !important; }
		/* the component sets display:inline !important, so this needs the extra class */
		.cs-card .cs-cta { display: none !important; }

		/* The logos are worth printing, but not frozen mid-scroll with tiles half cut off.
		   The three scrolling rows collapse into one wrapped grid so there are no orphans. */
		.dx-logowall { -webkit-mask-image: none !important; mask-image: none !important; flex-direction: row !important; flex-wrap: wrap !important; justify-content: center !important; }
		.dx-logowall__row { display: contents !important; animation: none !important; }
		/* Each row is printed twice for the seamless loop; on paper that is just duplicates */
		.dx-logowall__row .dx-logowall__tile:nth-child(n+9) { display: none !important; }

		body { background: #fff !important; }
		.ds-section { padding: var(--sp-6) 0 !important; background: #fff !important; }
		.dx-syshero { padding: var(--sp-6) 0 !important; background: #fff !important; color: #000 !important; }
		.dx-syshero h1, .dx-syshero__lead, .dx-syshero__eyebrow { color: #000 !important; }

		/* The stat band carries an inline dark background, hence the !important */
		.px-statband { background: #fff !important; }
		.px-statband__glow { display: none !important; }
		.px-statband h2, .px-stat__n, .px-stat__l, .px-statband p { color: #000 !important; }
		.px-stat__src { color: #555 !important; }
		.px-stat { border: 1px solid #ccc !important; background: #fff !important; }

		/* The three screens are a picture of a board the sentence above them already
		   describes, so they go the way the live board does. */
		.px-screens { display: none !important; }
		/* The phone screens are the argument rather than decoration, so they flatten
		   instead of disappearing: frames become outlines, and the notification and
		   the Take button keep their weight through borders rather than fills. */
		/* A dialog is display:none until it is opened, and it never opens on paper.
		   The champion handout is a real use of this page, so it prints inline
		   where it sits in the source, right under the kit it belongs to. */
		.px-open { display: none !important; }
		.px-modal { display: block !important; position: static !important; width: auto !important; max-width: none !important;
			max-height: none !important; overflow: visible !important; margin: var(--sp-5) 0 0 !important; border-color: #ccc !important; }
		.px-modal__in { max-height: none !important; overflow: visible !important; padding: 16px !important; }
		.px-modal__x { display: none !important; }
		.px-sms__frame { background: #fff !important; padding: 0 !important; box-shadow: none !important; }
		.px-sms__frame::before, .px-sms__frame::after { display: none !important; }
		.px-sms__notch, .px-sms__status, .px-sms__bar { display: none !important; }
		.px-sms__screen { height: auto !important; border: 1px solid #ccc !important; }
		.px-sms__av { background: #fff !important; color: #000 !important; border: 1.5px solid #000 !important; }
		.px-app__lock { background: #fff !important; padding: 0 8px 8px !important; }
		.px-app__clock { display: none !important; }
		.px-app__push { background: #fff !important; border: 1px solid #ccc !important; }
		.px-app__take { background: #fff !important; color: #000 !important; border: 2px solid #000 !important; }
		.px-app__held { background: #fff !important; border: 1px dashed #999 !important; }

		.px-reveal { opacity: 1 !important; transform: none !important; }

		/* Closed <details> would print empty */
		details > *:not(summary) { display: block !important; }
		.dx-pain summary::after, .ds-faq summary::after,
		.dx-fold > summary::after { content: "" !important; display: none !important; }
		/* Printed, the spec tables are the reason someone saves this page at all. */
		.dx-fold > summary { color: #000 !important; }

		.ds-card, .dx-topcard, .dx-kit__item, .px-cmp,
		.dx-objection, .dx-logowall__tile, .px-par, .px-par__unitline, .px-legend,
		.cs-card, .dx-phase, details { page-break-inside: avoid; }
		/* Three across is unreadable on paper; two keeps the metric legible. */
		.cs-grid { grid-template-columns: 1fr 1fr !important; }
		.cs-card:hover { transform: none !important; box-shadow: none !important; }
		h2, h3 { page-break-after: avoid; }
		.ew { border: 1px solid #ccc !important; box-shadow: none !important; page-break-inside: avoid; }
		.ew__big { color: #000 !important; }
		a[href^="#"], a[href^="http"] { text-decoration: none; color: inherit; }
	}
			.ew {
				background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
				box-shadow: var(--shadow-sm); padding: var(--sp-6) var(--sp-6) var(--sp-5);
				max-width: 940px; margin: var(--sp-6) auto 0;
			}
			.ew__head { text-align: center; margin-bottom: var(--sp-5); }
			.ew__head h3 { margin: var(--sp-2) 0 0; }
			.ew__controls { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-5); }
			.ew__ctrl label { display: block; font-size: var(--fs-small); color: var(--ink-soft); line-height: 1.35; min-height: 2.7em; }
			.ew__val { font-family: var(--font-mono); font-size: 1.9rem; font-weight: 800; color: var(--ink); line-height: 1.1; margin: var(--sp-2) 0 var(--sp-1); }
			.ew__val small { font-size: 0.95rem; font-weight: 600; color: var(--ink-faint); margin-left: 3px; }

			.ew input[type=range] {
				-webkit-appearance: none; appearance: none; width: 100%; height: 6px; margin: 0;
				background: var(--border); border-radius: var(--radius-pill); outline: none; cursor: pointer;
			}
			.ew input[type=range]::-webkit-slider-thumb {
				-webkit-appearance: none; appearance: none; width: 26px; height: 26px; border-radius: 50%;
				background: var(--accent); border: 3px solid var(--surface); box-shadow: 0 1px 5px rgba(0,0,0,.28); cursor: grab;
			}
			.ew input[type=range]::-moz-range-thumb {
				width: 20px; height: 20px; border-radius: 50%; background: var(--accent);
				border: 3px solid var(--surface); box-shadow: 0 1px 5px rgba(0,0,0,.28); cursor: grab;
			}
			.ew input[type=range]:focus-visible { box-shadow: 0 0 0 3px rgba(222,29,35,.25); }
			.ew__scale { display: flex; justify-content: space-between; font-size: 11px; color: var(--ink-faint); margin-top: 5px; }

			.ew__out { text-align: center; margin-top: var(--sp-6); padding-top: var(--sp-5); border-top: 1px solid var(--border); }
			.ew__big { font-family: var(--font-mono); font-size: clamp(2.8rem, 1.8rem + 4vw, 4.4rem); font-weight: 800; color: var(--accent); line-height: 1; }
			.ew__big span { font-size: 0.45em; font-weight: 700; margin-left: 6px; }
			.ew__cap { font-weight: 700; color: var(--ink); margin-top: var(--sp-2); font-size: 1.05rem; }
			.ew__half { color: var(--ink-soft); margin-top: var(--sp-3); }
			.ew__note { font-size: var(--fs-small); color: var(--ink-faint); margin: var(--sp-4) auto 0; max-width: 620px; line-height: 1.5; }
			.ew__trial { margin: var(--sp-5) auto 0; padding-top: var(--sp-4); border-top: 1px dashed var(--border); max-width: 640px; color: var(--ink-soft); }
			.ew__trial a { color: var(--accent); font-weight: 700; }

			@media (max-width: 760px) {
				.ew { padding: var(--sp-5) var(--sp-4); }
				.ew__controls { grid-template-columns: 1fr; gap: var(--sp-5); }
				.ew__ctrl label { min-height: 0; }
			}
		
