/* ROUND 3 KIT ---------------------------------------------------------------------------------------------------------
   The css half of the round-3 kit (ROUND3-RULES §12, A13). The js half is js/ui.js (ui.seg, ui.pageSwap, ui.flip, ui.morph,
   ui.recede, ui.kenburns, ui.countUp, ui.avatars, ui.pagerDots, ui.actionbar). Loaded after app.css (index.html), so a
   kit rule wins over an older rule of the same weight. Tokens come from css/tokens.css (the ROUND 3 TOKENS block): the
   radius scale, the four springs and their durations, --paper-press, --t-press, --actionbar-h, --p and --py.
   Motion here is transform and opacity only, with the four named exceptions of §4.1 (the ui.seg lens width, the pager
   height, the Plexus band height, the radius of a morphing photo). Reduce Motion: no travel, short colour changes.
   Contents: the segmented control · panes · the press language · the living hero and Ken Burns · the photo card ·
   the magazine · the highlights pager · the facts grid · the date rail · avatar stacks · the sticky action bar ·
   line drawings. ------------------------------------------------------------------------------------------------- */

/* ---- ui.seg (§7.1, GLASS §1.9.6). Built by ui.js only: div.mx-seg[role=tablist][data-seg] holding one .mx-seg-lens and
   one button.mx-seg-item[role=tab] per item (its label, an optional .mx-badge). A 44 px capsule track, items 36 px
   inside with a 44 px tap area, 14 px --font-ui 500, the selected item ink 600 on the raised lens. The lens is ONE
   element that travels (transform and width on the control spring, sampled keyframes ui.js plays, motion pass 1 Oct 2026:
   its css transition here ran on a linear() curve on the page's own thread), never a ::before per item. The [data-seg] attribute
   keeps these rules clear of the older route-tab rules for .mx-seg in app.css ---- */
.mx-seg[data-seg] { position: relative; isolation: isolate; display: flex; align-items: center; gap: 0; max-width: 100%; min-height: 44px; padding: 4px;
  box-sizing: border-box; border: 0; border-radius: var(--r-capsule); background: rgba(25,21,18,.06); box-shadow: inset 0 0 0 .5px rgba(25,21,18,.08);
  overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.mx-seg[data-seg]::-webkit-scrollbar { display: none; }
.mx-seg[data-seg] > .mx-seg-lens { position: absolute; z-index: 0; top: 4px; bottom: 4px; left: 0; width: 0; border-radius: var(--r-capsule); pointer-events: none;
  background: #fffdf8; box-shadow: 0 1px 3px rgba(25,21,18,.16), 0 0 0 .5px rgba(25,21,18,.04); opacity: 0; will-change: transform;
  transition: opacity 280ms linear; }
/* the lens fades in where it is first placed (280 ms), never appearing in one frame after its track (MI-09) */
.mx-seg[data-seg].is-placed > .mx-seg-lens { opacity: 1; }
.mx-seg[data-seg] > .mx-seg-item { position: relative; z-index: 1; flex: 1 0 auto; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 36px; margin: 0; padding: 0 16px; box-sizing: border-box; border: 0; border-radius: var(--r-capsule); background: none;
  font: 500 var(--fs-2nd)/20px var(--font-ui); letter-spacing: 0; text-transform: none; text-decoration: none; color: var(--soft); white-space: nowrap; cursor: pointer;
  -webkit-tap-highlight-color: transparent; -webkit-user-select: none; user-select: none; -webkit-user-drag: none; touch-action: manipulation;
  transition-property: color, transform; transition-duration: var(--t-quick), var(--spring-snappy-dur); transition-timing-function: var(--ease), var(--spring-snappy); }
/* a 44 px tap target for the 36 px item. An item never shrinks below its label (the track scrolls instead, §7.1) */
.mx-seg[data-seg] > .mx-seg-item::after { content: ""; position: absolute; left: 0; right: 0; top: -4px; bottom: -4px; }
.mx-seg[data-seg] > .mx-seg-item.is-lit { color: var(--ink); font-weight: 600; }
/* the pressed item gives a little (.96, §4.3: glass and ui.seg items .96, paper .97, tab bar items .92) */
.mx-seg[data-seg] > .mx-seg-item.is-pressed { transform: scale(.96); transition-duration: var(--t-quick), var(--t-press); transition-timing-function: var(--ease), var(--ease); }
/* the label reserves the width of its 600 weight, so lighting an item never reflows the row (and never moves the lens) */
.mx-seg-label { display: inline-grid; justify-items: center; }
.mx-seg-label::after { content: attr(data-label); font-weight: 600; height: 0; overflow: hidden; visibility: hidden; pointer-events: none; }
.mx-seg[data-seg] > .mx-seg-item > .mx-badge { min-width: 18px; height: 18px; padding: 0 5px; font-size: var(--fs-label); }
.mx-seg[data-seg] > .mx-seg-item > .mx-badge[hidden] { display: none; }
.mx-seg[data-seg] > .mx-seg-item:focus-visible { outline: 2px solid var(--crimson); outline-offset: -2px; }
@media (hover: hover) { .mx-seg[data-seg] > .mx-seg-item:not(.is-lit):hover { color: var(--ink); } }
/* small phones: the items share the row (four fit at 320 without a sideways scroll, and ui.seg keeps the selected one in view) */
@media (max-width: 400px) { .mx-seg[data-seg] > .mx-seg-item { flex: 1 1 auto; padding: 0 10px; } }
@media (max-width: 360px) { .mx-seg[data-seg] > .mx-seg-item { padding: 0 7px; font-size: 13px; } }
/* sticky: pinned under the top bar (ui.seg measures it into --mx-seg-top). Once content runs under it, ui.seg adds
   .is-stuck and .mx-glass: the light glass of app.css replaces the track's own tint. While the sticky action bar shows,
   the solid fallback (GLASS §1.6), so glass stays at three surfaces (§11) */
.mx-seg[data-seg].is-sticky { position: sticky; top: var(--mx-seg-top, 0px); z-index: 6; }
.mx-seg[data-seg].mx-glass { background: none; box-shadow: var(--glass-shadow); }
html.mx-actionbar-on .mx-seg[data-seg].mx-glass::before { background: var(--glass-solid-light); -webkit-backdrop-filter: none; backdrop-filter: none; }
@media (prefers-reduced-motion: reduce) {
  .mx-seg[data-seg] > .mx-seg-lens { transition: none; }
  .mx-seg[data-seg] > .mx-seg-item, .mx-seg[data-seg] > .mx-seg-item.is-pressed { transform: none; transition: color var(--t-rm-color) var(--ease); }
}
/* a ui.seg in a section head (.mx-sh) sits at its right end at its own width (My Med&X Upcoming and Past) */
.mx-sh > .mx-seg[data-seg] { flex: none; margin-left: auto; }
/* a row that centres a ui.seg in the page gutter with a hairline under it (the People and Inbox switch on wider
   screens). --wide: from 501 px only, phones keep the tab bar as the one way between the two */
.mx-switchrow { display: flex; justify-content: center; padding: 10px 36px; border-bottom: 1px solid var(--hair); box-sizing: border-box; }
.mx-switchrow > .mx-seg[data-seg] { flex: 0 1 auto; }
@media (max-width: 500px) { .mx-switchrow--wide { display: none !important; } }

/* ---- panes (§7.2): children of a pager container with data-pane="<key>". ui.pageSwap stacks the two during a swap, and the
   container never scroll-anchors mid-swap ---- */
[data-pane][hidden] { display: none !important; }
.mx-panes { position: relative; overflow-anchor: none; }

/* ---- the press language (§4.3). Paper buttons, rows and cards, and any child of a .mx-press wrapper, go down to .97 in
   100 ms while pressed and come back on --spring-snappy. The `scale` property, so a hover lift or any other transform of
   these elements stays their own. A frozen CTA builder is never edited for it: the view wraps its output in .mx-press.
   Only an element that is itself tappable (a link, a button, a data-act, data-nav or role=button element) takes the
   press. A stat tile, a row that only holds controls (a People row, a switch row) or a card with its own buttons stays
   still, so a tap moves one thing and a static block never looks tappable. js/ui.js PRESS_LANG mirrors these selectors.
   The transition list below is the whole of their colour and motion (it includes the colour changes they had). The
   view stylesheets load after this file, so the :root prefix and the tappable filter give the list the weight to win
   over a view's own list: (0,4,1), and (0,4,0) for the wrapper rule, against (0,3,0) for the heaviest view list
   (.mx-me-screen [data-act]:not(.mx-me-card)). The :active rule weighs more again, so its durations win while pressed. Reduce Motion: --paper-press is 1 (the
   tokens), and the press is a 120 ms dim instead ---- */
:root :is(a[href], button, [data-act], [data-nav], [role="button"]):is(.btn, .btn-primary, .btn-gold, .btn-ghost, .btn-ghost-ink, .btn-block, .btn-sm, .mx-row, .mx-person-row, .mx-pcard, .mx-linkcard, .mx-tile, .mx-glance-tile, .mx-photocard):not(.mx-no-press),
:root .mx-press > :is(a, button, [data-act]):not(.mx-no-press) {
  transition-property: background-color, border-color, color, box-shadow, opacity, transform, scale;
  transition-duration: var(--t-quick), var(--t-quick), var(--t-quick), var(--t-quick), var(--t-quick), var(--t-quick), var(--spring-snappy-dur);
  transition-timing-function: var(--ease), var(--ease), var(--ease), var(--ease), var(--ease), var(--ease), var(--spring-snappy);
}
:root :is(a[href], button, [data-act], [data-nav], [role="button"]):is(.btn, .btn-primary, .btn-gold, .btn-ghost, .btn-ghost-ink, .btn-block, .btn-sm, .mx-row, .mx-person-row, .mx-pcard, .mx-linkcard, .mx-tile, .mx-glance-tile, .mx-photocard):not(.mx-no-press):not([disabled]):not([aria-disabled="true"]):active,
:root .mx-press > :is(a, button, [data-act]):not(.mx-no-press):not([disabled]):not([aria-disabled="true"]):active,
/* smooth-member 3.1: the same press from js/ui.js installPress (.is-pressed in the pointerdown's task, the first frame) */
:root :is(a[href], button, [data-act], [data-nav], [role="button"]):is(.btn, .btn-primary, .btn-gold, .btn-ghost, .btn-ghost-ink, .btn-block, .btn-sm, .mx-row, .mx-person-row, .mx-pcard, .mx-linkcard, .mx-tile, .mx-glance-tile, .mx-photocard):not(.mx-no-press):not([disabled]):not([aria-disabled="true"]).is-pressed,
:root .mx-press > :is(a, button, [data-act]):not(.mx-no-press):not([disabled]):not([aria-disabled="true"]).is-pressed {
  scale: var(--paper-press); transform: none;
  transition-duration: var(--t-quick), var(--t-quick), var(--t-quick), var(--t-quick), var(--t-rm-color), var(--t-quick), var(--t-press);
  transition-timing-function: var(--ease), var(--ease), var(--ease), var(--ease), var(--ease), var(--ease), var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  :root :is(a[href], button, [data-act], [data-nav], [role="button"]):is(.btn, .btn-primary, .btn-gold, .btn-ghost, .btn-ghost-ink, .btn-block, .btn-sm, .mx-row, .mx-person-row, .mx-pcard, .mx-linkcard, .mx-tile, .mx-glance-tile, .mx-photocard):not(.mx-no-press):not([disabled]):not([aria-disabled="true"]):active,
  :root .mx-press > :is(a, button, [data-act]):not(.mx-no-press):not([disabled]):not([aria-disabled="true"]):active,
  :root :is(a[href], button, [data-act], [data-nav], [role="button"]):is(.btn, .btn-primary, .btn-gold, .btn-ghost, .btn-ghost-ink, .btn-block, .btn-sm, .mx-row, .mx-person-row, .mx-pcard, .mx-linkcard, .mx-tile, .mx-glance-tile, .mx-photocard):not(.mx-no-press):not([disabled]):not([aria-disabled="true"]).is-pressed,
  :root .mx-press > :is(a, button, [data-act]):not(.mx-no-press):not([disabled]):not([aria-disabled="true"]).is-pressed { opacity: .72; }
}

/* ---- the living hero (§6.1): .mx-hero.mx-hero--stage. Phones: 58 percent of the small viewport between 360 and 520 px
   (489 at 390 × 844, 371 at 320 × 640). From 501 px it keeps its DESIGN-RULES size. It recedes with scroll (ui.recede
   writes --p and --py): the photo layer moves at half speed and a second scrim darkens up to .35. The title, the line
   and the action scroll with the page and never fade. Nothing --p drives has a transition ---- */
@media (max-width: 500px) {
  .mx-hero.mx-hero--stage:not(.mx-hero--ink):not(.mx-hero--cream) { aspect-ratio: auto; min-height: 360px; max-height: 520px; height: 58vh; height: 58svh; }
}
.mx-hero--stage > .mx-hero-photo, .mx-hero--stage > .mx-kenburns { transform: translate3d(0, var(--py), 0); }
.mx-hero--stage::after { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; background: #191512; opacity: calc(var(--p) * .35); }
.mx-hero--stage > .mx-hero-body { z-index: 1; }

/* ---- the bold hero, direction C "House lights" (Alen picked C for everything, 1 Oct 2026, ROUND3-RULES 6.1 amended for its
   date figure). One component for Home's Today hero (views/home.css) and, since 5 Oct, the top of Projects and of every
   project page (.mx-hx below, js/views/_hx.js): the photo and everything lit with it in ONE layer (.mx-hx-fade) whose own alpha melts into the paper
   over the hero's last --hx-fade px, over the stage's amber (.mx-hx-under), so the photo never ends on a line. The lamp
   from the top left, the house light on the front rows, the words' one soft shade, and the date block: the day in the UI
   face's big figures, the gold month, the weekday, the mark's gold and crimson rule, the facts in two steps. Each screen
   sets its geometry (--hx-h, --hx-fade, --hx-body-b, --hx-g, --lift). Its colours are variables with Home's values (the
   stage's amber --hx-warm, the month and the rule's top --hx-month, the rule's foot --hx-rule, the ember --hx-ember), so a
   project top takes its own from the --proj-* tokens. Transform and opacity only move ---- */
.mx-hx-stage { position: absolute; inset: 0; z-index: 0; overflow: hidden; transform-origin: 50% 0; }
.mx-hx-fade { position: absolute; inset: 0;
  -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - var(--hx-fade)), rgba(0,0,0,.991) calc(100% - var(--hx-fade) * .9), rgba(0,0,0,.942) calc(100% - var(--hx-fade) * .8),
    rgba(0,0,0,.837) calc(100% - var(--hx-fade) * .7), rgba(0,0,0,.683) calc(100% - var(--hx-fade) * .6), rgba(0,0,0,.5) calc(100% - var(--hx-fade) * .5), rgba(0,0,0,.317) calc(100% - var(--hx-fade) * .4),
    rgba(0,0,0,.163) calc(100% - var(--hx-fade) * .3), rgba(0,0,0,.058) calc(100% - var(--hx-fade) * .2), rgba(0,0,0,.009) calc(100% - var(--hx-fade) * .1), rgba(0,0,0,0) 100%);
  mask-image: linear-gradient(180deg, #000 calc(100% - var(--hx-fade)), rgba(0,0,0,.991) calc(100% - var(--hx-fade) * .9), rgba(0,0,0,.942) calc(100% - var(--hx-fade) * .8),
    rgba(0,0,0,.837) calc(100% - var(--hx-fade) * .7), rgba(0,0,0,.683) calc(100% - var(--hx-fade) * .6), rgba(0,0,0,.5) calc(100% - var(--hx-fade) * .5), rgba(0,0,0,.317) calc(100% - var(--hx-fade) * .4),
    rgba(0,0,0,.163) calc(100% - var(--hx-fade) * .3), rgba(0,0,0,.058) calc(100% - var(--hx-fade) * .2), rgba(0,0,0,.009) calc(100% - var(--hx-fade) * .1), rgba(0,0,0,0) 100%); }

/* under the thinning photo the paper takes the stage's amber at up to 29 percent and gives it back to plain cream at the
   hero's edge, so the melt goes photo, amber, cream, never through khaki or black */
.mx-hx-under { position: absolute; left: 0; right: 0; bottom: 0; height: var(--hx-fade); pointer-events: none;
  background: linear-gradient(180deg, rgba(var(--hx-warm, 204, 136, 60), 0) 0%, rgba(var(--hx-warm, 204, 136, 60), .22) 26%, rgba(var(--hx-warm, 204, 136, 60), .29) 46%, rgba(var(--hx-warm, 204, 136, 60), .22) 64%, rgba(var(--hx-warm, 204, 136, 60), .10) 82%, rgba(var(--hx-warm, 204, 136, 60), 0) 100%); }
/* the house light reaching the front rows: a screen of the same amber over the photo's foot, so it warms as it thins */
.mx-hx-glow { position: absolute; left: 0; right: 0; bottom: 0; height: calc(var(--hx-fade) * 1.25); pointer-events: none; mix-blend-mode: screen;
  background: linear-gradient(180deg, rgba(var(--hx-warm, 204, 136, 60), 0) 0%, rgba(var(--hx-warm, 204, 136, 60), .12) 30%, rgba(var(--hx-warm, 204, 136, 60), .34) 62%, rgba(var(--hx-warm, 204, 136, 60), .52) 100%); }
/* the lamp at rest: the room's own warm light from the top left, a screen of gold that lifts the photo and never whitens */
.mx-hx-lamp { position: absolute; inset: 0; pointer-events: none; mix-blend-mode: screen;
  background: radial-gradient(90% 70% at 6% 0%, rgba(255, 186, 84, .30) 0%, rgba(255, 176, 72, .14) 34%, rgba(255, 176, 72, .04) 58%, rgba(255, 176, 72, 0) 76%); }

.mx-hx-shade { position: absolute; inset: 0; pointer-events: none; background:
  radial-gradient(var(--scrim-w) var(--scrim-h) at 0% calc(100% - var(--hx-body-b) - var(--scrim-y)), rgba(22, 17, 14, .74) 0%, rgba(22, 17, 14, .69) 36%, rgba(22, 17, 14, .50) 62%, rgba(22, 17, 14, .20) 84%, rgba(22, 17, 14, 0) 100%); }
.mx-hx-shade::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(60% 34% at 100% calc(100% - var(--hx-fade) * .9), rgba(var(--hx-ember, 126, 21, 27), .30) 0%, rgba(var(--hx-ember, 126, 21, 27), .10) 50%, rgba(var(--hx-ember, 126, 21, 27), 0) 80%); }

.mx-hx-when { display: flex; align-items: stretch; gap: 12px; max-width: 100%; margin-top: 18px; }
.mx-hx-date { display: flex; align-items: flex-start; gap: 8px; flex: none; }
.mx-hx-d { font: var(--fw-num) 58px/.8 var(--font-ui); letter-spacing: var(--ls-num); font-variant-numeric: tabular-nums lining-nums; padding-top: 3px; color: var(--cream); }
.mx-hx-d.mx-hx-d--long { font-size: 44px; }
.mx-hx-mw { display: flex; flex-direction: column; justify-content: space-between; gap: 6px; padding: 3px 0 1px; }
.mx-hx-m { font: 600 var(--fs-btn)/1 var(--font-ui); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--hx-month, #F8B018); }
.mx-hx-w { font: 400 var(--fs-2nd)/1 var(--font-ui); color: rgba(247, 241, 230, .82); white-space: nowrap; }
/* the small words of the date block carry a soft dark halo (the lock screen's legibility shadow), so a stage light behind a
   13 px month never takes it under 4.5 to 1 */
.mx-hx-m, .mx-hx-w, .mx-hx-f1, .mx-hx-f2 { text-shadow: 0 0 8px rgba(22, 17, 14, .55), 0 1px 2px rgba(22, 17, 14, .30); }
.mx-hx-rule { flex: none; width: 2px; border-radius: 1px; margin: 2px 2px 0; background: linear-gradient(180deg, var(--hx-month, #F8B018) 0 50%, var(--hx-rule, #9E1B22) 50% 100%); }
.mx-hx-facts { display: flex; flex-direction: column; justify-content: center; gap: 3px; min-width: 0; }
.mx-hx-f1 { font: 600 17px/22px var(--font-ui); letter-spacing: var(--ls-title3); color: var(--cream); }
[data-hx] { --scrim-w: 150%; --scrim-h: 50%; --scrim-y: 170px; }
@media (min-width: 501px) { [data-hx] { --scrim-w: 120%; --scrim-h: 46%; --scrim-y: 110px; } }
@media (min-width: 901px) { [data-hx] { --scrim-w: 100%; --scrim-h: 52%; --scrim-y: 100px; } }
[data-hx] .mx-hx-f2 { margin: 0; font: 400 15px/20px var(--font-ui); color: rgba(247, 241, 230, .84); font-variant-numeric: tabular-nums; }
@media (max-width: 360px) {
  .mx-hx-when { gap: 10px; margin-top: 14px; }
  .mx-hx-d { font-size: 44px; } .mx-hx-d.mx-hx-d--long { font-size: 36px; }
  .mx-hx-date { gap: 6px; }
  .mx-hx-f1 { font-size: 15px; line-height: 20px; } [data-hx] .mx-hx-f2 { font-size: var(--fs-2nd); line-height: 19px; }
  .mx-hx-f1, .mx-hx-f2 { white-space: nowrap; }
}
@media (min-width: 501px) {
  .mx-hx-when { margin-top: 22px; gap: 16px; }
  .mx-hx-d { font-size: 80px; } .mx-hx-d.mx-hx-d--long { font-size: 68px; }
  .mx-hx-mw { gap: 10px; padding-top: 5px; }
  .mx-hx-f1 { font-size: 19px; line-height: 24px; }
  [data-hx] .mx-hx-f2 { font-size: 16px; line-height: 22px; }
}
@media (min-width: 901px) { .mx-hx-d { font-size: 92px; } .mx-hx-d.mx-hx-d--long { font-size: 80px; } }

/* ---- the project tops (.mx-hx, js/views/_hx.js; Alen, 5 Oct 2026, build 11: Projects and each project page open on the
   Home hero). Home's numbers exactly (views/home.css › .mx-home, the Today card): the height, the melt, the gutter on the
   page column (Home's 1108 px column is the 1180 px .mx-p less its 36 px sides, so the words stand on the page's edge),
   the title's scale (42, 36 at 360 and under, 64 from 501, 76 from 901), the chip, the date block, the one action beside
   the date from 501 px, and Home's light: the lamp from the top left, the house light on the photo's foot, the words' one
   shade, the melt into the paper over the last --hx-fade px over the stage's warm light. The page sets its photo's crop
   (--pos, --lift) and its colours. The photo drifts in its frame (ui.kenburns) and, on a phone, moves a little slower than
   the scroll (--py from ui.recede at .56, as Home's). The words take grid areas, so a page without a chip, a date or an
   action keeps the same rows.
   One difference from Home's markup, none on screen: the photo is the section's own first child and the light lies over
   it in layers of its own (_hx.js hxLight, the melt as .mx-hx-melt below, the same pixels as Home's mask over its amber).
   So the router, growing a card's photo into this one, finds the words, the melt and the shade beside the photo and fades
   them in over it (router.js › overPhoto, the first four in the tree, which is why the tree reads crumbs, words, melt,
   shade, lamp, house light, and z-index draws them in their own order). .mx-hx--fold: a top whose box the screen sizes and
   moves itself (the Plexus header, which folds into its 200 px band): the kit leaves it its box and its scrim ---- */
.mx-hx { --hx-fade: 160px; --hx-body-b: 48px; --hx-g: var(--gutter-p); --hx-h: calc(100vw * 1.25 + 84px); --lift: 0px; --pos: 50% 50%; --hx-melt: var(--hx-fade); }
@media (min-width: 501px) { .mx-hx { --hx-fade: 220px; --hx-body-b: 90px; --hx-g: 36px; --hx-h: min(660px, 80vw); } }
@media (min-width: 901px) { .mx-hx { --hx-h: clamp(540px, 78vh, 640px); --hx-g: max(36px, calc((100vw - 1108px) / 2)); } }
@media (max-width: 360px) { .mx-hx { --hx-h: min(calc(100vw * 1.25 + 84px), max(368px, 65vh)); } }
.mx-hero.mx-hx[data-hx]:not(.mx-hero--ink):not(.mx-hero--cream):not(.mx-hx--fold) {
  display: block; height: var(--hx-h); aspect-ratio: auto; min-height: 0; max-height: none; width: 100%; margin: 0; border-radius: 0;
  overflow: hidden; background: var(--ink); color: var(--cream); isolation: isolate; -webkit-mask-image: none; mask-image: none; transform: none; }
/* the kit's own veils are off: the hero melts into the paper, so it has no edge to veil and no band behind its words */
.mx-hero.mx-hx[data-hx]::after { content: none; }
.mx-hx[data-hx]:not(.mx-hx--fold) > .mx-scrim, .mx-hx[data-hx] > .mx-hero-body::before { display: none; }
/* the photo (the page's own, then the Ken Burns layer that adopts it): lifted in its frame by --lift (the part above the
   hero's top never shows) and cropped on --pos */
.mx-hero.mx-hx:not(.mx-hx--fold) > :is(.mx-hero-photo, .mx-kenburns) { position: absolute; left: 0; right: 0; top: calc(-1 * var(--lift)); bottom: 0; width: 100%; height: auto;
  max-width: none; transform: none; }
.mx-hero.mx-hx:not(.mx-hx--fold) > .mx-hero-photo { display: block; height: calc(100% + var(--lift)); object-fit: cover; }
.mx-hx > .mx-hero-photo, .mx-hx > .mx-kenburns > img { object-position: var(--pos); }
@media (max-width: 500px) { .mx-hero.mx-hx:not(.mx-hx--fold) > :is(.mx-hero-photo, .mx-kenburns) { transform: translate3d(0, calc(var(--py, 0px) * .56), 0); } }
/* the light over the photo, drawn in this order whatever the tree's order: the lamp and the house light, the words' shade,
   the melt over all three (as inside Home's melting layer), then the words and the way back */
.mx-hx > :is(.mx-hx-lamp, .mx-hx-glow) { z-index: 1; }
.mx-hx > .mx-hx-shade { z-index: 2; }
.mx-hx > .mx-hx-melt { z-index: 3; }
/* the words: bottom left, --hx-body-b above the hero's foot, so every cream word stands on the photo and only the action
   reaches into the melt */
.mx-hx > .mx-hx-body { position: absolute; z-index: 6; left: 0; right: 0; bottom: var(--hx-body-b); width: auto; max-width: none; margin: 0; padding: 0 var(--hx-g);
  box-sizing: border-box; display: grid; grid-template-columns: minmax(0, 1fr); grid-template-areas: "chip" "title" "when" "more" "cta"; justify-items: start; align-items: end; }
.mx-hx > .mx-hx-body > * { max-width: none; }
.mx-hx > .mx-hx-body > .mx-tag { grid-area: chip; margin: 0 0 6px; min-height: 28px; padding: 0 12px; font: 600 13px/1 var(--font-ui); letter-spacing: 0; text-transform: none; }
.mx-hx .mx-hx-title { grid-area: title; margin: 0; font: var(--fw-display) 42px/1.02 var(--font-display); letter-spacing: -.012em; color: var(--cream); text-wrap: balance; font-optical-sizing: auto; }
/* the title upright in one colour, as Home's: the flair is the scale, the date and the light, never an italic accent word */
.mx-hx .mx-hx-title i { color: inherit; font-style: normal; }
.mx-hx > .mx-hx-body > :is(.mx-hx-when, .mx-hx-line) { grid-area: when; }
.mx-hx > .mx-hx-body > .mx-hero-cta { grid-area: cta; margin-top: 20px; justify-self: stretch; width: 100%; }
.mx-hx .mx-when { white-space: nowrap; font-variant-numeric: tabular-nums lining-nums; }
/* a page whose key fact is no one day (the Accelerator, Building Bridges, Projects): one line in the date block's words */
.mx-hx .mx-hx-line { margin: 14px 0 0; font: 400 17px/24px var(--font-ui); color: rgba(247, 241, 230, .88); font-variant-numeric: tabular-nums;
  text-shadow: 0 0 8px rgba(22, 17, 14, .55), 0 1px 2px rgba(22, 17, 14, .30); }
/* a top with no action on a phone (Projects, Building Bridges without a next evening): its words stand where Home's stand
   above its action, never down in the melt */
@media (max-width: 500px) { .mx-hx > .mx-hx-body:not(:has(> .mx-hero-cta:not([hidden]))) { bottom: calc(var(--hx-body-b) + 68px); } }
@media (max-width: 360px) { .mx-hx > .mx-hx-body:not(:has(> .mx-hero-cta:not([hidden]))) { bottom: calc(var(--hx-body-b) + 64px); } }
/* a shell's empty date block holds the real one's size, so nothing moves when it lands (each page holds its own action) */
.mx-hx .mx-hx-when--ph { height: 50px; }
@media (max-width: 360px) {
  .mx-hx .mx-hx-title { font-size: 36px; }
  .mx-hx > .mx-hx-body > .mx-hero-cta { margin-top: 16px; }
  .mx-hx .mx-hx-when--ph { height: 42px; }
  .mx-hx .mx-hx-line { font-size: 15px; line-height: 20px; }
}
/* wider screens: the title across the top, the date block under it and the action under the date block, all on the
   words' left edge, as Home's from build 12 (Alen, 5 Oct: "not off to the right, below the dates"). The words sit 68 px
   lower than when the action stood beside the dates (--hx-body-b 158 to 90), as Home's, so the title and the dates keep
   their place and only the action reaches into the melt. Plexus's keynote faces stand under the date block, the action
   last, as on a phone */
@media (min-width: 501px) {
  .mx-hx > .mx-hx-body { grid-template-columns: minmax(0, 1fr); grid-template-areas: "chip" "title" "when" "more" "cta"; }
  .mx-hx > .mx-hx-body > .mx-tag { margin-bottom: 10px; }
  .mx-hx .mx-hx-title { font-size: 64px; line-height: 1; }
  .mx-hx .mx-hx-line { margin-top: 18px; font-size: 19px; line-height: 26px; }
  .mx-hx > .mx-hx-body > .mx-hero-cta { justify-self: start; width: auto; margin: 24px 0 0; }
  .mx-hx > .mx-hx-body > .mx-hero-cta > * { width: auto; padding-left: 30px; padding-right: 30px; }
  .mx-hx .mx-hx-when--ph { height: 67px; }
  /* the date row holds Home's date block (its 22 px over the 67 px figures), so on every top the title and the action stand
     where Home's stand: a one-line top (the Accelerator, Bridges, Projects) or the Forum's shorter "28–29" left them 10 to
     51 px lower (critic, 5 Oct 2026). The line or the block keeps to the row's top, under the title, as on Home */
  .mx-hx > .mx-hx-body { grid-template-rows: auto auto minmax(89px, auto) auto auto; }
  .mx-hx > .mx-hx-body > :is(.mx-hx-when, .mx-hx-line) { align-self: start; }
}
@media (min-width: 901px) {
  .mx-hx .mx-hx-title { font-size: 76px; }
  .mx-hx .mx-hx-when--ph { height: 77px; }
  .mx-hx > .mx-hx-body { grid-template-rows: auto auto minmax(99px, auto) auto auto; }
}
/* the way back on a wide screen: the breadcrumb, a glass capsule on the photo under the floating bar (the hero is the
   screen's first block, so the bar floats over it as over Home's, chrome.js › heroFirstWide). Phones carry Back in the top
   bar, so it is not drawn there */
.mx-hx > .mx-hx-crumbs { position: absolute; z-index: 7; top: 16px; left: var(--hx-g); gap: 10px; margin: 0; font: 600 var(--fs-label)/16px var(--font-ui); letter-spacing: .12em; }
body.mx-wfloat .mx-hx > .mx-hx-crumbs { top: calc(env(safe-area-inset-top, 0px) + 76px); }
.mx-hx-crumbs > a { color: rgba(247, 241, 230, .80); text-decoration: none; }
.mx-hx-crumbs > [aria-current] { color: var(--cream); }
.mx-hx-crumbs > .mx-hx-sep { color: rgba(247, 241, 230, .55); }
@media (hover: hover) { .mx-hx-crumbs > a:hover { color: var(--cream); } }
.mx-hx-crumbs > a:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; border-radius: var(--r-xs); }
@media (max-width: 500px) { .mx-hx > .mx-hx-crumbs { display: none; } }
/* the melt as a layer OVER the photo (the project tops, _hx.js hxLight): the same light as Home's .mx-hx-fade over its
   .mx-hx-under, as two gradients: the paper at the alpha the mask leaves out less the amber's share, over the stage's
   amber at the share that composites to the same pixel (the mask's 11 stops, the under-melt's curve read at each). It
   covers the photo, the lamp and the shade beneath it. --hx-melt is its length (the hero's --hx-fade) */
.mx-hx-melt { position: absolute; inset: 0; pointer-events: none; background:
  linear-gradient(180deg, rgba(247, 241, 230, 0) calc(100% - var(--hx-melt)), rgba(247, 241, 230, .008) calc(100% - var(--hx-melt) * .9), rgba(247, 241, 230, .048) calc(100% - var(--hx-melt) * .8),
    rgba(247, 241, 230, .125) calc(100% - var(--hx-melt) * .7), rgba(247, 241, 230, .232) calc(100% - var(--hx-melt) * .6), rgba(247, 241, 230, .363) calc(100% - var(--hx-melt) * .5),
    rgba(247, 241, 230, .522) calc(100% - var(--hx-melt) * .4), rgba(247, 241, 230, .686) calc(100% - var(--hx-melt) * .3), rgba(247, 241, 230, .835) calc(100% - var(--hx-melt) * .2),
    rgba(247, 241, 230, .936) calc(100% - var(--hx-melt) * .1), rgba(247, 241, 230, 1) 100%),
  linear-gradient(180deg, rgba(var(--hx-warm, 204, 136, 60), 0) calc(100% - var(--hx-melt)), rgba(var(--hx-warm, 204, 136, 60), .001) calc(100% - var(--hx-melt) * .9), rgba(var(--hx-warm, 204, 136, 60), .010) calc(100% - var(--hx-melt) * .8),
    rgba(var(--hx-warm, 204, 136, 60), .044) calc(100% - var(--hx-melt) * .7), rgba(var(--hx-warm, 204, 136, 60), .111) calc(100% - var(--hx-melt) * .6), rgba(var(--hx-warm, 204, 136, 60), .215) calc(100% - var(--hx-melt) * .5),
    rgba(var(--hx-warm, 204, 136, 60), .337) calc(100% - var(--hx-melt) * .4), rgba(var(--hx-warm, 204, 136, 60), .480) calc(100% - var(--hx-melt) * .3), rgba(var(--hx-warm, 204, 136, 60), .648) calc(100% - var(--hx-melt) * .2),
    rgba(var(--hx-warm, 204, 136, 60), .859) calc(100% - var(--hx-melt) * .1), rgba(var(--hx-warm, 204, 136, 60), .86) 100%); }
/* each project's own colour (css/tokens.css › the project accents): the stage's warm light under the melt and on the
   photo's foot, a soft step of its accent; the month and the rule's top in its light step (AA on the photo's shade); the
   rule's foot and the ember in its own. Plexus Week and Projects keep the house's amber, gold and crimson (Home's) */
.mx-hx[data-hx="gala"] { --hx-warm: 217, 189, 127; --hx-month: var(--proj-gala-lt); --hx-rule: var(--proj-gala); --hx-ember: 128, 96, 32; }
.mx-hx[data-hx="accelerator"] { --hx-warm: 232, 168, 104; --hx-month: var(--proj-accelerator-lt); --hx-rule: var(--proj-accelerator); --hx-ember: 154, 79, 20; }
.mx-hx[data-hx="forum"] { --hx-warm: 148, 189, 172; --hx-month: var(--proj-forum-lt); --hx-rule: var(--proj-forum); --hx-ember: 63, 93, 82; }
.mx-hx[data-hx="bridges"] { --hx-warm: 155, 184, 216; --hx-month: var(--proj-bridges-lt); --hx-rule: var(--proj-bridges); --hx-ember: 53, 80, 112; }

/* ---- Ken Burns (ui.kenburns, §4.1 class A): the layer at the back of a hero or band, one photo on top at a time. The
   drift and the crossfades are Web Animations run by ui.js. The photo settle never runs on this layer. The name is not
   .mx-kb: the iOS app puts that class on <html> while the keyboard shows (medx-native.js), and this rule then pinned the
   whole page ---- */
.mx-kenburns { position: absolute; inset: 0; overflow: hidden; background: var(--ink); }
.mx-kenburns > .mx-kenburns-img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; display: block; object-fit: cover; transform-origin: 50% 50%; }
#view .mx-kenburns > .mx-kenburns-img.mx-hero-photo { animation: none; }

/* ---- the photo card (§12, A15): .mx-photocard holding .mx-media.r-4x5 (its image, a .mx-scrim, an optional
   .mx-tag--glass), then .mx-photocard-body with .mx-photocard-title and .mx-photocard-meta. --r-lg, clipped with the
   isolation and WebKit mask of §2 so the corners never flash square while a child animates. The media touches the card
   edge, so it takes the card's corners through the clip and sets none of its own.
   --tall: the week cards (a 22 px display title, room for one sentence and the tags on the body).
   --keynote: the one rectangular person (§8), a gold Keynote tag, the name, the role in small caps, the institution ---- */
.mx-photocard { position: relative; display: flex; flex-direction: column; min-width: 0; overflow: hidden; isolation: isolate; -webkit-mask-image: -webkit-radial-gradient(white, black);
  border-radius: var(--r-lg); background: var(--card, #fdfaf3); color: var(--ink); text-decoration: none; }
.mx-photocard::after { content: ""; position: absolute; inset: 0; z-index: 2; border-radius: inherit; pointer-events: none; box-shadow: inset 0 0 0 .5px rgba(25,21,18,.10); }
.mx-photocard > .mx-media { flex: none; border-radius: 0; -webkit-mask-image: none; }
.mx-photocard > .mx-media > .mx-scrim { background: linear-gradient(180deg, rgba(25,21,18,.40) 0, rgba(25,21,18,0) 96px); }
.mx-photocard > .mx-media > .mx-tag--glass { position: absolute; top: 12px; left: 12px; z-index: 1; max-width: calc(100% - 24px); overflow: hidden; text-overflow: ellipsis; }
.mx-photocard-body { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; padding: 14px 16px 16px; min-width: 0; }
.mx-photocard-title { margin: 0; font: 600 var(--fs-title3)/24px var(--font-ui); letter-spacing: var(--ls-title3); color: var(--ink); }
.mx-photocard-meta { margin: 0; font: 400 var(--fs-2nd)/20px var(--font-ui); color: var(--soft); }
.mx-photocard-body .mx-tag { border-radius: var(--r-xs); }
.mx-photocard--tall .mx-photocard-body { gap: 8px; padding: 16px 18px 18px; }
.mx-photocard--tall .mx-photocard-title { font: var(--fw-title2) var(--fs-title2)/28px var(--font-display); letter-spacing: var(--ls-title2); }
.mx-photocard--keynote .mx-photocard-role { font: 600 var(--fs-2nd)/20px var(--font-ui); font-variant-caps: all-small-caps; letter-spacing: .04em; color: var(--soft); }
.mx-photocard--keynote .mx-photocard-inst { font: 400 var(--fs-2nd)/20px var(--font-ui); color: var(--ink); }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .mx-photocard .mx-media > img { transition: transform var(--spring-enter-dur) var(--spring-enter); }
  .mx-photocard:hover .mx-media > img { transform: scale(1.04); }
}

/* ---- the magazine (§12): .mx-mag holding a .mx-mag-lead (a 16:9 image card with its title), then .mx-mag-row rows (a 56 px
   thumbnail at --r-sm, a title, a date) ---- */
.mx-mag { display: flex; flex-direction: column; min-width: 0; }
.mx-mag-lead { position: relative; display: flex; flex-direction: column; overflow: hidden; isolation: isolate; -webkit-mask-image: -webkit-radial-gradient(white, black);
  border-radius: var(--r-lg); background: var(--card, #fdfaf3); color: var(--ink); text-decoration: none; }
.mx-mag-lead::after { content: ""; position: absolute; inset: 0; z-index: 2; border-radius: inherit; pointer-events: none; box-shadow: inset 0 0 0 .5px rgba(25,21,18,.10); }
.mx-mag-lead > .mx-media { flex: none; border-radius: 0; -webkit-mask-image: none; }
.mx-mag-body { display: flex; flex-direction: column; gap: 4px; padding: 14px 16px 16px; }
.mx-mag-title { margin: 0; font: 600 var(--fs-title3)/24px var(--font-ui); letter-spacing: var(--ls-title3); color: var(--ink); }
.mx-mag-date { font: 600 var(--fs-label)/16px var(--font-ui); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--soft); font-variant-numeric: tabular-nums; }
.mx-mag-row { display: grid; grid-template-columns: 56px minmax(0, 1fr); align-items: center; align-content: center; column-gap: 14px; row-gap: 2px; min-height: 80px;
  padding: 12px 0; box-sizing: border-box; border-top: 1px solid var(--hair-soft); color: var(--ink); text-decoration: none; }
.mx-mag-lead + .mx-mag-row { margin-top: 8px; border-top: 0; }
.mx-mag-row > .mx-media { grid-row: 1 / span 2; width: 56px; height: 56px; aspect-ratio: 1 / 1; border-radius: var(--r-sm); }
.mx-mag-row > .mx-mag-title { font-size: var(--fs-body); line-height: 22px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
@media (hover: hover) { .mx-mag-row:hover > .mx-mag-title, .mx-mag-lead:hover .mx-mag-title { color: var(--crimson); } }

/* ---- the highlights pager (§12): .mx-pager, a horizontal snap scroller of large cards, one fact per card, each full
   width inside the gutter. ui.pagerDots(pager) adds .mx-pager-dots under it ---- */
.mx-pager { display: flex; gap: 12px; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scrollbar-width: none;
  -webkit-overflow-scrolling: touch; padding: 0 var(--gutter-p); scroll-padding: 0 var(--gutter-p); }
.mx-pager::-webkit-scrollbar { display: none; }
.mx-pager > .mx-pager-item { position: relative; flex: 0 0 100%; min-width: 0; scroll-snap-align: start; scroll-snap-stop: always; overflow: hidden; isolation: isolate;
  -webkit-mask-image: -webkit-radial-gradient(white, black); border-radius: var(--r-lg); background: var(--card, #fdfaf3); color: var(--ink); text-decoration: none; }
.mx-pager > .mx-pager-item > .mx-media { border-radius: 0; -webkit-mask-image: none; }
@media (min-width: 501px) { .mx-pager { padding: 0; scroll-padding: 0; } }
.mx-pager-dots { display: flex; justify-content: center; align-items: center; gap: 8px; padding-top: 12px; }
.mx-pager-dots[hidden] { display: none; }
/* dots a screen tore down stay as they show (ui.pagerDots › destroy). A view that puts its own still copy right after the
   pager (home.js) gets one row: the kit's still row after that copy steps aside */
.mx-pager-dots:not([data-mx-still]) + .mx-pager-dots[data-mx-still] { display: none; }
.mx-pager-dot { width: 6px; height: 6px; border-radius: 50%; background: rgba(25,21,18,.22);
  transition: background-color var(--t-quick) var(--ease), scale var(--spring-snappy-dur) var(--spring-snappy); }
.mx-pager-dot.is-on { background: var(--ink); scale: 1.25; }

/* ---- the facts grid (§12): .mx-glance, 2 by 2 "At a glance" tiles at --r-lg, each an icon, a value (.mx-glance-v, a
   figure: --font-ui 600, tabular) and a label (.mx-glance-l) ---- */
.mx-glance { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.mx-glance-tile { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; min-width: 0; min-height: 104px; padding: 16px; box-sizing: border-box;
  border-radius: var(--r-lg); background: var(--card, #fdfaf3); box-shadow: inset 0 0 0 .5px rgba(25,21,18,.10); color: var(--ink); text-decoration: none; }
.mx-glance-tile > svg, .mx-glance-tile > .mx-ic { flex: none; color: var(--crimson); }
.mx-glance-v { margin-top: auto; font: var(--fw-num) 20px/26px var(--font-ui); letter-spacing: var(--ls-num); font-variant-numeric: tabular-nums; color: var(--ink); overflow-wrap: anywhere; }
.mx-glance-l { font: 400 var(--fs-2nd)/20px var(--font-ui); color: var(--soft); }

/* ---- the date rail (§12): .mx-rail holding .mx-rail-track (its fill runs to today, --fill on the rail as a percentage)
   with the .mx-rail-today marker, then one .mx-rail-chip per confirmed date (a tag: --r-xs, a dot tinted per project
   through --cat, for example style="--cat: var(--cat-plexus)") ---- */
.mx-rail { --fill: 0%; position: relative; min-width: 0; }
.mx-rail-track { position: relative; height: 2px; margin: 8px 5px 0; border-radius: 1px; background: rgba(25,21,18,.12); }
.mx-rail-track::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: var(--fill); border-radius: inherit; background: var(--crimson); }
.mx-rail-today { position: absolute; top: 50%; left: var(--fill); width: 10px; height: 10px; margin: -5px 0 0 -5px; border-radius: 50%; background: var(--crimson); box-shadow: 0 0 0 3px var(--cream); }
.mx-rail-chips { display: flex; gap: 8px; margin-top: 14px; overflow-x: auto; scrollbar-width: none; }
.mx-rail-chips::-webkit-scrollbar { display: none; }
.mx-rail-chip { flex: none; display: inline-flex; align-items: center; gap: 6px; min-height: 28px; padding: 0 10px; box-sizing: border-box; border-radius: var(--r-xs);
  background: rgba(25,21,18,.05); font: 600 var(--fs-label)/16px var(--font-ui); letter-spacing: .06em; text-transform: uppercase; color: var(--ink);
  white-space: nowrap; font-variant-numeric: tabular-nums; }
.mx-rail-chip::before { content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--cat, var(--gold)); }
.mx-rail-chip.is-past { color: var(--soft); }
@keyframes mx-ring-pop { from { transform: scale(0); } }
@media (prefers-reduced-motion: no-preference) { .mx-rail-today { animation: mx-ring-pop var(--spring-ring-dur) var(--spring-ring) backwards; } }

/* ---- avatar stacks (§8, ui.avatars): 28 px on cream, 36 px on photos, each face over the one before by 8 or 12 px with
   a 2 px ring in the ground colour, at most 4 faces, then a +n circle of the same size (12 px, tabular) ---- */
.mx-avatars { --s: 28px; --o: 8px; --ring: var(--cream); display: inline-flex; align-items: center; flex: none; vertical-align: middle; }
.mx-avatars--36 { --s: 36px; --o: 12px; }
.mx-avatars > * { position: relative; flex: none; width: var(--s); height: var(--s); box-sizing: border-box; border-radius: 50%; overflow: hidden; box-shadow: 0 0 0 2px var(--ring); }
.mx-avatars > * + * { margin-left: calc(var(--o) * -1); }
.mx-avatar { background: var(--ink); }
.mx-avatar-i { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font: 600 max(12px, calc(var(--s) * .4))/1 var(--font-ui); color: var(--gold); }
.mx-avatar > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.mx-avatars-more { display: inline-flex; align-items: center; justify-content: center; width: auto; min-width: var(--s); padding: 0 4px; border-radius: var(--r-capsule);
  background: #efe7d8; color: var(--ink); font: 600 var(--fs-label)/1 var(--font-ui); font-variant-numeric: tabular-nums; }
/* the keynote row on a hero photo: a 1.5 px light ring and the glass edge, no blur per face (GLASS §1.8) */
.mx-avatars--photo { --ring: rgba(247,241,230,.55); }
.mx-avatars--photo > * { box-shadow: 0 0 0 1.5px var(--ring), inset 0 1px 0 rgba(255,255,255,.22); }
.mx-avatars--photo > .mx-avatars-more { background: rgba(25,21,18,.55); color: var(--cream); }

/* ---- the sticky action bar (§11, A14): a glass bar floating above the tab bar with one proxy button that forwards its
   tap to the hero's frozen element. It slides in on the ui spring once that element has left the screen. Reduce Motion
   fades its glass layer and its button instead (never the glass element's own opacity, GLASS §1.4). The third glass
   surface of GLASS §1.1. Its inner radius is the button's --r-md, so the bar takes --r-md plus its 8 px padding ---- */
.mx-actionbar { position: fixed; z-index: 29; left: 21px; right: 21px; bottom: max(var(--mx-tabbar-h), calc(12px + env(safe-area-inset-bottom, 0px)));
  max-width: 440px; height: var(--actionbar-h); margin: 0 auto; padding: 8px; box-sizing: border-box; border-radius: calc(var(--r-md) + 8px);
  transform: translateY(calc(100% + 24px + var(--mx-tabbar-h))); visibility: hidden;
  transition: transform var(--spring-dur) var(--spring), visibility 0s linear var(--spring-dur); }
.mx-actionbar.is-shown { transform: none; visibility: visible; transition: transform var(--spring-dur) var(--spring), visibility 0s; }
.mx-actionbar-btn { display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%; height: 48px; min-height: 48px; margin: 0; padding: 0 16px; box-sizing: border-box;
  border: 0; border-radius: var(--r-md); background: var(--crimson); color: var(--cream); font: 600 var(--fs-btn)/1 var(--font-ui); letter-spacing: var(--ls-caps);
  text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.mx-actionbar-btn.btn-gold { background: var(--gold); color: var(--ink); }
@media (max-width: 374px) { .mx-actionbar { left: 12px; right: 12px; } }
@media (prefers-reduced-motion: reduce) {
  .mx-actionbar, .mx-actionbar.is-shown { transform: none; }
  .mx-actionbar { transition: visibility 0s linear var(--t-rm-fade); box-shadow: none; }
  .mx-actionbar.is-shown { transition: visibility 0s; box-shadow: var(--glass-shadow); }
  .mx-actionbar::before, .mx-actionbar > .mx-actionbar-btn { opacity: 0; transition: opacity var(--t-rm-fade) linear; }
  .mx-actionbar.is-shown::before, .mx-actionbar.is-shown > .mx-actionbar-btn { opacity: 1; }
}

/* ---- line drawings (§12, D4): .mx-illus holds a drawn map (assets/maps/world.svg, assets/zagreb/map.svg). Gold line
   1.5 px, #a38a4f on cream and #c9a962 on ink, no fill, labels in HTML beside it ---- */
.mx-illus { display: block; color: #a38a4f; }
.mx-illus > svg, .mx-illus > img { display: block; width: 100%; height: auto; }
.mx-illus svg :is(path, line, polyline, polygon, circle, ellipse, rect) { fill: none; stroke: currentColor; stroke-width: 1.5; vector-effect: non-scaling-stroke; }
:is(.mx-ink, .mx-dark, .card-ink) .mx-illus, .mx-illus--ink { color: #c9a962; }
