/* ============================================================
   Hextech frames (2026-10-31, James: "a more hard-edged, League of Legends, ArtCraft, grid-like structure", with the type kept in
   Google's Material style). First on ECS, then on every live page ("repeat this touch for every other page"). A layer over each
   page; layout, copy and the Google Sans / M3 type scale are untouched. Scoped to body.hxf (not .hx: rx.css already uses .hx for
   the ECS solution panels; putting .hx on body collapsed that page). Linked last on Home, Work, ECS, Crew Check-In, Franklin, Vision.
   - League: cards lose their round corners for chamfered frames (top-left and bottom-right cut), a hairline rim that runs
     along the cuts, an inner second hairline (the client's double border) and bright L-ticks on the two square corners.
   - ArtCraft: the page shows its grid (hairline columns at the 12-column edges, quarters and centre). Home already is a
     hairline grid of compartments, so there only its media panels and portrait are framed.
   No numbered section labels ("01 / Role" etc.): James never wants those anywhere in the portfolio (2026-10-31).
   Device mockups, chat bubbles, product screens and the contact buttons keep their own shapes. fx.js reads --hx-c to clip
   its hover glow to the same chamfer.
   ============================================================ */
body.hxf { --hx-line: rgba(225, 227, 228, .24); --hx-line-2: rgba(225, 227, 228, .55); --hx-tick: rgba(255, 255, 255, .75); --hx-grid: rgba(255, 255, 255, .045);
  --hx-c: 22px; }

/* ---------- the grid, shown (pages built on main.wrap) ---------- */
body.hxf main.wrap {
  background-image: linear-gradient(var(--hx-grid), var(--hx-grid)), linear-gradient(var(--hx-grid), var(--hx-grid)), linear-gradient(var(--hx-grid), var(--hx-grid)),
    linear-gradient(var(--hx-grid), var(--hx-grid)), linear-gradient(var(--hx-grid), var(--hx-grid));
  background-size: 1px 100%; background-repeat: no-repeat;
  background-position: calc(50% - var(--g-w12) / 2) 0, calc(50% - var(--g-w12) / 4) 0, 50% 0, calc(50% + var(--g-w12) / 4) 0, calc(50% + var(--g-w12) / 2) 0; }

/* ---------- chamfered frames ----------
   ECS: .mx-card .gx-promo .mx-chart .bn-vis .rm-collage .rm-tile .rm-media .rx-vis .sx-c .gm-media .gm-hero .qm-card
   Work: .pc-c   Crew Check-In / Franklin: .gs-hero-media .px-media .px-icon .px-bigtype .px-card.text .px-col .gs-facts.cs li
   Vision: .mx-card .gm-media   Home: .vibe .im, .ph .im, .portrait */
body.hxf :is(.mx-card, .gx-promo, .mx-chart, .bn-vis, .rm-collage, .rm-tile, .rm-media, .rx-vis, .sx-c, .gm-media, .gm-hero, .qm-card,
  .pc-c, .gs-hero-media, .px-media, .px-icon, .px-bigtype, .px-card.text, .px-col, .gs-facts.cs li, .vibe .im, .ph .im, .portrait) {
  border-radius: 0 !important;
  clip-path: polygon(var(--hx-c) 0, 100% 0, 100% calc(100% - var(--hx-c)), calc(100% - var(--hx-c)) 100%, 0 100%, 0 var(--hx-c));
  box-shadow: inset 0 0 0 1px var(--hx-line); outline: 1px solid rgba(255, 255, 255, .07); outline-offset: -7px; }
body.hxf :is(.mx-card, .gx-promo, .mx-chart, .qm-card, .px-icon, .px-bigtype, .px-card.text, .px-col, .gs-facts.cs li, .vibe .im, .ph .im, .portrait) { position: relative; }
/* the rim along the two cuts, and L-ticks on the square corners */
body.hxf :is(.mx-card, .gx-promo, .mx-chart, .bn-vis, .rm-collage, .rm-tile, .rm-media, .rx-vis, .sx-c, .gm-media, .gm-hero, .qm-card,
  .pc-c, .gs-hero-media, .px-media, .px-icon, .px-bigtype, .px-card.text, .px-col, .gs-facts.cs li, .vibe .im, .ph .im, .portrait)::after {
  content: ""; position: absolute; inset: 0; z-index: 5; pointer-events: none;
  background:
    linear-gradient(135deg, transparent calc(50% - .7px), var(--hx-line-2) 50%, transparent calc(50% + .7px)) top left / var(--hx-c) var(--hx-c) no-repeat,
    linear-gradient(135deg, transparent calc(50% - .7px), var(--hx-line-2) 50%, transparent calc(50% + .7px)) bottom right / var(--hx-c) var(--hx-c) no-repeat,
    linear-gradient(var(--hx-tick), var(--hx-tick)) top right / 16px 1.5px no-repeat,
    linear-gradient(var(--hx-tick), var(--hx-tick)) top right / 1.5px 16px no-repeat,
    linear-gradient(var(--hx-tick), var(--hx-tick)) bottom left / 16px 1.5px no-repeat,
    linear-gradient(var(--hx-tick), var(--hx-tick)) bottom left / 1.5px 16px no-repeat; }
/* smaller cuts on small tiles and fact chips */
body.hxf :is(.rm-tile, .gs-facts.cs li, .px-icon) { --hx-c: 12px; }
/* hard edges inside the frames too */
body.hxf :is(.mx-card, .gx-promo, .mx-chart, .rm-tile, .rm-media, .rx-vis, .sx-c, .gm-media, .gm-hero, .qm-card, .gs-hero-media, .px-media, .vibe .im, .ph .im, .vx-card) > :is(img, video) { border-radius: 0; }   /* direct children only: device mockups inside keep their screens */

/* ---------- top bar (2026-10-31, James: "change the nav back to fit the look and feel of the rest of the portfolio") ----------
   the floating bar becomes a chamfered frame like the cards (rim along the cuts, inner hairline, L-ticks); its link highlights,
   the Contact Me button and the avatar lose their pill / circle shapes for small chamfers */
body.hxf header.hud { --hx-c: 14px; border-radius: 0;
  clip-path: polygon(var(--hx-c) 0, 100% 0, 100% calc(100% - var(--hx-c)), calc(100% - var(--hx-c)) 100%, 0 100%, 0 var(--hx-c));
  box-shadow: inset 0 0 0 1px var(--hx-line); outline: 1px solid rgba(255, 255, 255, .06); outline-offset: -5px; }
body.hxf header.hud::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(135deg, transparent calc(50% - .7px), var(--hx-line-2) 50%, transparent calc(50% + .7px)) top left / var(--hx-c) var(--hx-c) no-repeat,
    linear-gradient(135deg, transparent calc(50% - .7px), var(--hx-line-2) 50%, transparent calc(50% + .7px)) bottom right / var(--hx-c) var(--hx-c) no-repeat,
    linear-gradient(var(--hx-tick), var(--hx-tick)) top right / 12px 1.5px no-repeat, linear-gradient(var(--hx-tick), var(--hx-tick)) top right / 1.5px 12px no-repeat,
    linear-gradient(var(--hx-tick), var(--hx-tick)) bottom left / 12px 1.5px no-repeat, linear-gradient(var(--hx-tick), var(--hx-tick)) bottom left / 1.5px 12px no-repeat; }
body.hxf header.hud a.it span { border-radius: 0; clip-path: polygon(6px 0, 100% 0, 100% calc(100% - 6px), calc(100% - 6px) 100%, 0 100%, 0 6px); }
body.hxf header.hud a.go { --hx-c: 10px; border-radius: 0 !important;
  clip-path: polygon(var(--hx-c) 0, 100% 0, 100% calc(100% - var(--hx-c)), calc(100% - var(--hx-c)) 100%, 0 100%, 0 var(--hx-c)); }
body.hxf header.hud .mark .av { border-radius: 0; clip-path: polygon(7px 0, 100% 0, 100% calc(100% - 7px), calc(100% - 7px) 100%, 0 100%, 0 7px); }

/* ---------- top bar as the League client's (2026-10-31, James: "refer to the navigation that league has", screenshot of the
   client bar) — replaces the chamfered floating pill above. Full-width bar flush to the top, dark gradient, hairline along the
   bottom. Left: the avatar in a ringed emblem with the primary action (Contact Me, the client's PLAY) attached, its right end
   pointed; then the pages as spaced uppercase labels, the current one lit by a soft column. Right: a divider, LinkedIn, and a
   darker profile panel (name + Available), like the summoner block. Type stays Google Sans. */
body.hxf header.hud { position: sticky; top: 0; width: 100%; max-width: none; height: 64px; margin: 0; padding: 0 0 0 18px; border-radius: 0; clip-path: none;
  background: linear-gradient(180deg, #1c1d20 0%, #121315 100%); outline: 0; backdrop-filter: none; -webkit-backdrop-filter: none;
  box-shadow: inset 0 -1px 0 rgba(225, 227, 228, .3), 0 1px 0 rgba(0, 0, 0, .6), 0 10px 30px rgba(0, 0, 0, .35); }
body.hxf header.hud::after { background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .55) 50%, transparent) bottom / 60% 1px no-repeat; inset: auto 0 0 0; height: 1px; }
body.hxf header.hud .grp { height: 100%; align-items: center; gap: 0; }
/* emblem: the avatar in a double ring */
body.hxf header.hud .mark { position: relative; z-index: 2; padding: 0; height: auto; }
body.hxf header.hud .mark .av { width: 46px; height: 46px; border-radius: 50%; clip-path: none; border: 2px solid #c4c7c8;
  box-shadow: 0 0 0 3px #121315, 0 0 0 4px rgba(225, 227, 228, .45), 0 4px 12px rgba(0, 0, 0, .6); }
/* the primary action, attached to the emblem with a pointed right end (the client's PLAY) */
body.hxf header.hud a.go { --hx-c: 0px; height: 38px; margin-left: -10px; padding: 0 34px 0 26px; border-radius: 0 !important;
  clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 50%, calc(100% - 16px) 100%, 0 100%);
  font: 500 .8125rem/1 var(--display); letter-spacing: .12em; text-transform: uppercase; }
/* pages: spaced uppercase labels; the current one lit by a soft column */
body.hxf header.hud nav[aria-label="Primary"] { height: 100%; margin-left: 22px; gap: 0; }
body.hxf header.hud nav[aria-label="Primary"] a.it { height: 100%; padding: 0 20px; }
body.hxf header.hud a.it span { padding: 0; border-radius: 0; clip-path: none; background: none !important; font: 500 .875rem/1 var(--display);
  letter-spacing: .14em; text-transform: uppercase; color: #9aa0a6; }
body.hxf header.hud a.it:hover span, body.hxf header.hud a.it[aria-current] span { color: #fff; }
body.hxf header.hud nav[aria-label="Primary"] a.it[aria-current] { background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, .07) 100%);
  box-shadow: inset 0 -2px 0 rgba(255, 255, 255, .85); }
/* right side: divider, LinkedIn, then the profile panel */
body.hxf header.hud nav.sep { height: 100%; margin: 0; padding: 0 22px; border-left: 1px solid rgba(225, 227, 228, .16); }
body.hxf header.hud nav.sep a.it span { letter-spacing: .1em; }
body.hxf header.hud .hud-me { display: flex; flex-direction: column; justify-content: center; gap: 4px; height: 100%; padding: 0 26px;
  background: linear-gradient(180deg, #0f1012, #0b0c0d); border-left: 1px solid rgba(225, 227, 228, .2); }
body.hxf header.hud .hud-me b { font: 500 .9375rem/1.1 var(--display); letter-spacing: .02em; color: #f1f3f4; }
body.hxf header.hud .hud-me span { display: flex; align-items: center; gap: 7px; font: 400 .75rem/1 var(--display); color: #c4c7c8; }
body.hxf header.hud .hud-me i { width: 7px; height: 7px; border-radius: 50%; background: #fff; box-shadow: 0 0 6px rgba(255, 255, 255, .8); }
@media (max-width: 760px) { body.hxf header.hud { height: 56px; padding-left: 10px; } body.hxf header.hud .hud-me { display: none; }
  body.hxf header.hud a.go { padding: 0 26px 0 20px; } body.hxf header.hud nav[aria-label="Primary"] { margin-left: 8px; } body.hxf header.hud nav[aria-label="Primary"] a.it { padding: 0 12px; } }
/* smaller bar, no profile panel (2026-10-31, James: "no need for the James Kim online ... resize the nav to be smaller") */
body.hxf header.hud { height: 48px; padding-left: 14px; }
body.hxf header.hud .mark .av { width: 34px; height: 34px; border-width: 1.5px; box-shadow: 0 0 0 2px #121315, 0 0 0 3px rgba(225, 227, 228, .45), 0 3px 8px rgba(0, 0, 0, .6); }
body.hxf header.hud a.go { height: 28px; margin-left: -8px; padding: 0 26px 0 20px; font-size: .6875rem;
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 50%, calc(100% - 12px) 100%, 0 100%); }
body.hxf header.hud nav[aria-label="Primary"] { margin-left: 16px; }
body.hxf header.hud nav[aria-label="Primary"] a.it { padding: 0 16px; }
body.hxf header.hud a.it span { font-size: .75rem; }
body.hxf header.hud nav.sep { padding: 0 18px; }
@media (max-width: 760px) { body.hxf header.hud { height: 44px; } }
/* Contact Me back at the right end, after LinkedIn (2026-10-31, James); it keeps the League button shape */
body.hxf header.hud a.go { margin: 0 14px 0 4px; }
body.hxf header.hud nav[aria-label="Primary"] { margin-left: 22px; }
/* name banner replaces the wire avatar (2026-10-31, James: League profile banner "CYANIDE" — portrait on the left fading
   gradually into the bar, name in spaced capitals beside it, a faint diagonal sheen across). Photo: images/nav-james.png,
   cropped from hero/james-figure.png (transparent, so the bar shows through). */
body.hxf header.hud .mark { position: relative; display: flex; align-items: center; width: 190px; height: 100%; margin-left: -14px; padding: 0; overflow: hidden;
  background: linear-gradient(90deg, #26272b 0%, #1c1d20 45%, transparent 100%); }
body.hxf header.hud .mark::before { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(115deg, transparent 38%, rgba(255, 255, 255, .07) 48%, transparent 58%); }
body.hxf header.hud .mark .av { position: absolute; left: 0; top: 0; width: 82px; height: 100%; object-fit: cover; object-position: 40% 20%;
  border: 0; border-radius: 0; clip-path: none; box-shadow: none;
  -webkit-mask-image: linear-gradient(90deg, #000 35%, transparent 100%); mask-image: linear-gradient(90deg, #000 35%, transparent 100%); }
body.hxf header.hud .mark .mk-nm { position: relative; z-index: 2; margin-left: 66px; font: 500 .875rem/1 var(--display); letter-spacing: .2em;
  text-transform: uppercase; color: #f1f3f4; text-shadow: 0 1px 6px rgba(0, 0, 0, .8); }
body.hxf header.hud nav[aria-label="Primary"] { margin-left: 6px; }

/* ---------- dialogs (2026-10-31, James: "fix all modals to fit the new stylings") ----------
   .mdl (Aggressive Pickup, design programs, startups) and ECS's #howMore get the card frame: chamfered corners, rim along the
   cuts, L-ticks, inner hairline. The rim and ticks are background layers with the default `scroll` attachment, so they stay
   on the frame while a long dialog scrolls. Inside: square-cut close button, chamfered stat / invitation boxes, spaced
   capital eyebrow like the Work cards, and Contact in the nav's pointed League button shape. */
body.hxf dialog:is(.mdl, .hx-dlg) { --hx-c: 22px; border-radius: 0 !important;
  clip-path: polygon(var(--hx-c) 0, 100% 0, 100% calc(100% - var(--hx-c)), calc(100% - var(--hx-c)) 100%, 0 100%, 0 var(--hx-c));
  outline: 1px solid rgba(255, 255, 255, .07); outline-offset: -7px;
  background:
    linear-gradient(135deg, transparent calc(50% - .7px), var(--hx-line-2) 50%, transparent calc(50% + .7px)) top left / var(--hx-c) var(--hx-c) no-repeat,
    linear-gradient(135deg, transparent calc(50% - .7px), var(--hx-line-2) 50%, transparent calc(50% + .7px)) bottom right / var(--hx-c) var(--hx-c) no-repeat,
    linear-gradient(var(--hx-tick), var(--hx-tick)) top right / 16px 1.5px no-repeat, linear-gradient(var(--hx-tick), var(--hx-tick)) top right / 1.5px 16px no-repeat,
    linear-gradient(var(--hx-tick), var(--hx-tick)) bottom left / 16px 1.5px no-repeat, linear-gradient(var(--hx-tick), var(--hx-tick)) bottom left / 1.5px 16px no-repeat,
    #1f2022 !important;
  box-shadow: inset 0 0 0 1px var(--hx-line) !important; }
body.hxf dialog:is(.mdl, .hx-dlg)::backdrop { background: rgba(8, 9, 10, .72); }
body.hxf dialog .mdl-im, body.hxf dialog .mdl-im img { border-radius: 0 !important; }
/* close: square-cut, hairline rim, light on hover */
body.hxf dialog :is(.mdl-x, .hx-close) { --c: 8px; border-radius: 0 !important; background: #2a2b2e !important; color: #e1e3e4 !important;
  clip-path: polygon(var(--c) 0, 100% 0, 100% calc(100% - var(--c)), calc(100% - var(--c)) 100%, 0 100%, 0 var(--c));
  box-shadow: inset 0 0 0 1px rgba(225, 227, 228, .3) !important; outline-offset: -4px; }
body.hxf dialog :is(.mdl-x, .hx-close):is(:hover, :focus-visible) { background: #e1e3e4 !important; color: #151618 !important; }
/* eyebrow like the Work cards */
body.hxf dialog .mdl-k { font: 500 .75rem/1.4 var(--display, "Google Sans") !important; letter-spacing: .08em !important; text-transform: uppercase !important; color: #9aa0a6 !important; }
/* stat and invitation boxes */
body.hxf dialog :is(.mdl-stats li, .mdl-invite) { --c: 10px; border-radius: 0 !important; background: #26272a !important;
  clip-path: polygon(var(--c) 0, 100% 0, 100% calc(100% - var(--c)), calc(100% - var(--c)) 100%, 0 100%, 0 var(--c));
  box-shadow: inset 0 0 0 1px rgba(225, 227, 228, .16); }
/* Contact: the nav's pointed button */
body.hxf dialog a[data-contact]:is(.ac-btn, .gs-btn, .go) { border-radius: 0 !important; padding-right: 30px !important;
  clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 50%, calc(100% - 14px) 100%, 0 100%);
  font-family: var(--display, "Google Sans"); letter-spacing: .12em; text-transform: uppercase; font-size: .75rem; }
/* nav Contact Me: a plain rectangle the full height of the bar, flush to the right edge (2026-10-31, James) */
body.hxf header.hud a.go { height: 100%; margin: 0; padding: 0 28px; clip-path: none; border-radius: 0 !important; }
body.hxf header.hud .grp:last-child { padding-right: 0; margin-right: 0; }
/* no Home item; the banner reads "James Kim" and is the way home (2026-10-31, James) */
body.hxf header.hud .mark { width: 230px; }

/* one hairline, never two (2026-10-31, James: "double check every screen for any 2 hairlines meeting ... rather 1"):
   the inner second hairline (outline at −5…−7px) is dropped from every frame, dialog and the bar; the rim stays */
body.hxf :is(.mx-card, .gx-promo, .mx-chart, .bn-vis, .rm-collage, .rm-tile, .rm-media, .rx-vis, .sx-c, .gm-media, .gm-hero, .qm-card,
  .pc-c, .gs-hero-media, .px-media, .px-icon, .px-bigtype, .px-card.text, .px-col, .gs-facts.cs li, .vibe .im, .ph .im, .portrait),
body.hxf header.hud, body.hxf dialog:is(.mdl, .hx-dlg) { outline: 0 !important; }
/* name banner, second pass (2026-10-31, James: too wide, and the cut-out read like a selection of the figure): the photo is now
   a strip of the real photo (images/nav-james.jpg, background and all, from hero/cover-james.webp) that fades gradually into
   the bar from about a third of the way across; the name overlaps the fade; tighter width; a faint tint over the photo */
body.hxf header.hud .mark { width: auto; padding-right: 22px; margin-left: -14px;
  background: linear-gradient(90deg, rgba(255, 255, 255, .05), transparent 85%); }
body.hxf header.hud .mark .av { width: 104px; object-fit: cover; object-position: 38% 40%; filter: saturate(.75) brightness(.85) contrast(1.05);
  -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 30%, rgba(0, 0, 0, .55) 62%, transparent 100%);
          mask-image: linear-gradient(90deg, #000 0%, #000 30%, rgba(0, 0, 0, .55) 62%, transparent 100%); }
body.hxf header.hud .mark .mk-nm { margin-left: 84px; letter-spacing: .16em; white-space: nowrap; }
body.hxf header.hud .mark::before { background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, .06) 42%, transparent 54%); }
/* grid: only the two 12-column edge lines, which land on the content edges and read as one line with them; the quarter and
   centre lines ran 2–12px beside card edges in the gaps and read as doubled hairlines (2026-10-31) */
body.hxf main.wrap { background-image: linear-gradient(var(--hx-grid), var(--hx-grid)), linear-gradient(var(--hx-grid), var(--hx-grid));
  background-position: calc(50% - var(--g-w12) / 2) 0, calc(50% + var(--g-w12) / 2) 0; }
/* hero fact boxes (Crew Check-In, Franklin): four boxes 12px apart each had their own rim, so neighbours read as doubled lines;
   they are now one chamfered panel with single shared 1px dividers (the panel ground shows through 1px gaps) */
body.hxf .gs-facts.cs { --c: 12px; position: relative; gap: 1px !important; padding: 1px; width: fit-content; background: rgba(225, 227, 228, .24);
  clip-path: polygon(var(--c) 0, 100% 0, 100% calc(100% - var(--c)), calc(100% - var(--c)) 100%, 0 100%, 0 var(--c)); }
body.hxf .gs-facts.cs li { clip-path: none !important; box-shadow: none !important; background: #1f2022 !important; }
body.hxf .gs-facts.cs li::after { content: none !important; }
body.hxf .gs-facts.cs::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(135deg, transparent calc(50% - .7px), var(--hx-line-2) 50%, transparent calc(50% + .7px)) top left / var(--c) var(--c) no-repeat,
    linear-gradient(135deg, transparent calc(50% - .7px), var(--hx-line-2) 50%, transparent calc(50% + .7px)) bottom right / var(--c) var(--c) no-repeat; }
/* rotating banner photos (navpic.js): faces sit between 30% and 50% across, so the fade starts later */
body.hxf header.hud .mark .av { object-position: 50% 50%;
  -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 48%, rgba(0, 0, 0, .5) 72%, transparent 100%);
          mask-image: linear-gradient(90deg, #000 0%, #000 48%, rgba(0, 0, 0, .5) 72%, transparent 100%); }

/* ---------- line length (2026-11-01, James: "no line of text should be wider than 50-60 characters") ----------
   Base cap at zero specificity, so components that already set a narrower width keep it; anything set wider is capped
   individually below. Google Sans "0" is wide: 1ch ≈ 1.45 characters of prose, so 48ch ≈ 55 characters. Product screens and mockups are excluded.
   Check with _tools/measure-audit.js. */
:where(body.hxf) :where(p, blockquote, dd, h1, h2, h3, h4, figcaption:not(:has(> :is(p, h1, h2, h3, h4, h5, div)))):not(:where(.pc-shot, .pm-vid, .gx-composite, .vd, .pf, .ib-box, .md-box, .cw, .cam-world, .hl-stage, .ss-scene, .rx-ui, .sx-thread, .cw-chat, .ok-ph, .dk-box, .ioc, svg, header.hud) *) { max-width: 48ch; }
/* components that set a wider measure (640–960px copy blocks, leads, section intros): capped explicitly, centred ones stay centred */
body.hxf main :is(.gs-sec-hd .gs-sub, .sx-head p, .rx-head > p, .cw-text > p, .gm-card figcaption p, .gm-wide figcaption p, .mx-hd .mx-s,
  .gx-about-t, .gs-lead, .px-statement > p, .px-left > p) { max-width: 48ch; }
body.hxf main :is(.sx-head p, .mx-hd .mx-s, .cw-text > p, .px-statement > p) { margin-inline: auto; }
body.hxf .pc.full :is(.pc-s, .pc-t) { max-width: min(40%, 48ch); }
body.hxf :is(dialog .mdl-rows .v, .gx-promo-t > span, .plate-title .sub) { display: block; max-width: 48ch; }
/* Impact list thumbnails (Home, under the map): small, square-cut, no rim, so they don't double the row hairlines */
body.hxf .id .impact .ph .im { --hx-c: 6px; box-shadow: none !important; width: 52px !important; height: 52px !important; min-height: 0 !important; flex: none; }
body.hxf .id .impact .ph .im::after { content: none !important; }
body.hxf .id .impact .ph .im img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* scroll ruler (ac.js, right edge "0 000%" + ticks) removed site-wide (2026-11-01, James) */
.ruler { display: none !important; }
/* ECS quote carousel spans the 12-column width, meeting the page's grid lines (2026-11-01, James); the edge fade is shorter */
body.hxf section.pull.qm { padding-inline: max(24px, calc((100% - var(--g-w12)) / 2)); }
body.hxf section.pull.qm .qm-viewport { -webkit-mask-image: linear-gradient(90deg, transparent, #000 2.5%, #000 97.5%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 2.5%, #000 97.5%, transparent); }
/* ECS inbox close-up centred in its card (2026-11-01, James): the panel is scaled to 80% of the card width, so it starts at 10% */
body.hxf .ib-box .ib-panel { left: 10%; }

/* ---------- ECS card thumbnail, premium pass (2026-11-01, James: "looks so basic"), shared by Home (.pm-e2) and Work (.pc-shot.e2) ----------
   Selective Attention / Von Restorff: the Crew Member Lookup desktop recedes (greyscale, dimmed) and only the ECS Inbox panel is lit,
   by a second copy of the screen clipped to the panel (ui-lookup-inbox-clear.svg: x 954.5–1273, y 77.5–742 of 1363×803), with a soft
   halo behind it; the pilot phone stays lit in front. Uniform Connectedness: the dashed route becomes a light trail — a faint rail
   with a bright comet travelling from Contact AA into the inbox, landing on a pulsing node (the FIND MATCH light language).
   Cognitive load: the calendar detail no longer competes. Reduced motion: still comet hidden, no pulse. */
:is(.pm-e2, .pc-shot.e2) .e2-desk { position: absolute; }
:is(.pm-e2, .pc-shot.e2) .e2-desk > img:not(.e2-spot) { filter: grayscale(1) brightness(.42) contrast(1.05); }
:is(.pm-e2, .pc-shot.e2) .e2-desk .e2-spot { position: absolute; inset: 0; width: 100%; height: auto;
  clip-path: inset(9.65% 6.6% 7.6% 70.03% round 6px); filter: drop-shadow(0 0 18px rgba(255, 255, 255, .25)); }
:is(.pm-e2, .pc-shot.e2) .e2-desk::before { content: ""; position: absolute; z-index: -1; left: 62%; top: -8%; width: 44%; height: 116%; pointer-events: none;
  background: radial-gradient(closest-side, rgba(255, 255, 255, .16), transparent); }
:is(.pm-e2, .pc-shot.e2) .e2-phone { box-shadow: 0 0 0 1px rgba(255, 255, 255, .18), 0 30px 60px rgba(0, 0, 0, .7), 0 0 40px rgba(255, 255, 255, .06) !important; }
:is(.pm-e2, .pc-shot.e2) .e2-link path { animation: none !important; filter: none; stroke-dasharray: none; }
:is(.pm-e2, .pc-shot.e2) .e2-link .e2-rail { fill: none; stroke: rgba(255, 255, 255, .28); stroke-width: 1.5; stroke-linecap: round; }
:is(.pm-e2, .pc-shot.e2) .e2-link .e2-comet { fill: none; stroke: #fff; stroke-width: 2.5; stroke-linecap: round; stroke-dasharray: 16 100 !important;
  animation: e2Comet 2.6s cubic-bezier(.45, 0, .25, 1) infinite !important; }
:is(.pm-e2, .pc-shot.e2) .e2-link .e2-comet.e2-blur { stroke-width: 7; opacity: .7; }
:is(.pm-e2, .pc-shot.e2) .e2-link .e2-start { fill: #fff; stroke: none; filter: drop-shadow(0 0 4px #fff); }
:is(.pm-e2, .pc-shot.e2) .e2-link .e2-core { fill: #fff; stroke: none; }
:is(.pm-e2, .pc-shot.e2) .e2-link .e2-ring { fill: none; stroke: #fff; stroke-width: 1.5; transform-box: fill-box; transform-origin: center;
  animation: e2Ping 2.6s ease-out infinite; }
@keyframes e2Comet { from { stroke-dashoffset: 16; } 70%, to { stroke-dashoffset: -100; } }
@keyframes e2Ping { 0%, 62% { transform: scale(1); opacity: 0; } 66% { opacity: 1; } 100% { transform: scale(3.4); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { :is(.pm-e2, .pc-shot.e2) .e2-link .e2-comet { display: none; } :is(.pm-e2, .pc-shot.e2) .e2-link .e2-ring { animation: none; opacity: .5; } }
/* phone: dimmed too, with only the Contact AA card lit (dashboard-inbox-light.png 393×852: card ≈ y 238–329, x 17–375), so the light
   trail visibly starts at the action the pilot takes; the landing node is dark-cored so it reads on the white inbox */
.pc-shot.e2 .e2-phone { --pad: .7cqw; } .pm-e2 .e2-phone { --pad: 1.13cqw; }
:is(.pm-e2, .pc-shot.e2) .e2-phone { position: absolute; }
:is(.pm-e2, .pc-shot.e2) .e2-phone > img:not(.e2-spot) { filter: grayscale(1) brightness(.5); }
:is(.pm-e2, .pc-shot.e2) .e2-phone .e2-spot { position: absolute; top: var(--pad); left: var(--pad); width: calc(100% - 2 * var(--pad)); height: auto;
  clip-path: inset(27.9% 4.6% 61.4% 4.3% round 8px); filter: drop-shadow(0 0 12px rgba(255, 255, 255, .3)); }
:is(.pm-e2, .pc-shot.e2) .e2-link .e2-rail { stroke: rgba(255, 255, 255, .45); }
:is(.pm-e2, .pc-shot.e2) .e2-link .e2-core { fill: #151618; stroke: #fff; stroke-width: 2; }
:is(.pm-e2, .pc-shot.e2) .e2-link .e2-ring { stroke: #fff; }
:is(.pm-e2, .pc-shot.e2) .e2-link .e2-rail { stroke-dasharray: none !important; }   /* older rules dashed every path */
