/*
 * ericville26 — UX landing
 * ========================
 * Styles CORE WordPress blocks only. Every selector below targets markup the
 * block editor produces on its own (wp-block-group, wp-block-columns,
 * wp-block-quote, wp-block-buttons, wp-block-list …), reached through a
 * className the author sets in the sidebar. Nothing here needs a custom block,
 * a plugin, a shortcode or a slider, so the page stays fully editable in
 * Gutenberg and survives this theme.
 *
 * The register is a startup landing page: a claim, then evidence. Section
 * order follows 04-POSITIONING —
 *
 *   claim → figures (with the denominator stated in public) → method → the
 *   work → the dated AI trail → the endorsements → the ask
 *
 * Receipts sat between the trail and the endorsements until #1442; Eric traded
 * that list for more voices, so its rules are deleted rather than orphaned.
 *
 * The denominator paragraph under the figures is NOT decoration and must never
 * be demoted to fine print. An activation number without its denominator is
 * the exact thing that lost a real interview, so this page states the
 * definition at body size, on its own raised surface, directly beneath the
 * numbers it defines.
 *
 * Everything resolves through the theme tokens (--ink --text --muted --faint
 * --line --accent --accent-soft --bg --paper --serif --sans --col --gut --r-s
 * --r-m --r-l --fast --med --slow --ease --spring). There is not a single
 * hard-coded colour, so dark mode and the blue [data-section="ux"] accent both
 * come for free — verify at /ux/?ev26theme=dark.
 *
 * Borders are rationed. A rule appears only where it separates two things that
 * would otherwise be confused: the claim from the evidence, and the date axis
 * of the trail from its prose. Everywhere else separation is space, a --paper
 * fill, or type.
 *
 * Cascade notes (load order is v26-ux → basetags → page-ux → v26-base):
 *   - basetags.css carries `.main .content > * {max-width:…;margin:0 auto}` at
 *     (0,2,1) and loads AFTER this file, so the section-rhythm rule is written
 *     as `.content.ev26.ux-landing > *` (0,3,0) to win honestly rather than
 *     with !important.
 *   - basetags.css also styles bare `section` with its own padding/margin, so
 *     every group in the page markup is a plain <div> (the block default), not
 *     tagName:"section". Do not switch them back.
 */

/* ── page shell + section rhythm ─────────────────────
 * One measure, one gutter, one vertical interval for every top-level section.
 * The page's whole grid is this rule. */
.content.ev26.ux-landing > *{
  max-width:var(--col);
  margin-left:auto;margin-right:auto;
  padding-left:var(--gut);padding-right:var(--gut);
}
.content.ev26.ux-landing > * + *{margin-top:84px}
.ux-landing{padding-bottom:8px}

/* This one rule is load-bearing and easy to delete by accident.
 *
 * ericville26 is a CLASSIC theme with no theme.json, so WordPress renders every
 * core group block as
 *
 *     <div class="wp-block-group MYCLASS">
 *       <div class="wp-block-group__inner-container">…children…</div>
 *     </div>
 *
 * The wrapper carries no styling role, but it means a group that declares
 * display:flex has exactly ONE flex item -- the wrapper -- so every flex
 * layout below (the section heads, the work cards, the gap between a card
 * title and its body, the margin-top:auto that pins a card's meta line to the
 * bottom) silently does nothing and the section quietly stacks instead.
 *
 * display:contents dissolves the wrapper for layout purposes without touching
 * the DOM, so the group's real children become its layout children. It is also
 * forward-compatible: if this theme later gains a theme.json and WordPress
 * stops emitting the wrapper, nothing here needs to change. */
.ux-landing .wp-block-group__inner-container{display:contents}

/* ── the claim ───────────────────────────────────────
 * A statement, not a page title. Sized just under the home hero so the site
 * still has one loudest moment, and set to 17ch so it breaks into three
 * deliberate lines at desktop. */
.ux-landing .is-style-ev26-claim{padding-top:78px}
/* The section marker (#1493), the SAME component the Lab opener uses: a 28px
   accent rule, then the label. It is `.micro` from v26-base.css carrying a
   page-specific colour and the rule — deliberately not a second eyebrow style,
   so /ux/ and /lab/ open in one visual language. The base .micro is --faint;
   the marker is --accent because it is naming the section, not captioning it. */
.ux-landing .is-style-ev26-claim .ux-kind{
  display:flex;align-items:center;gap:12px;
  color:var(--accent);margin:0 0 18px;
}
.ux-landing .is-style-ev26-claim .ux-kind::before{
  content:"";width:28px;height:2px;background:var(--accent);flex:0 0 28px;
}
.ux-landing .ev26-eyebrow{
  font-family:var(--sans);font-size:var(--t-label);font-weight:700;
  letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--accent);
  margin:0 0 22px;
}
/* display:block is deliberate, not defensive noise. basetags.css carries
   `h1:not(.show){display:none}` at (0,1,1) -- an ericville25 rule that hid a
   dummy heading -- and without this the entire claim renders invisible while
   the deck below it renders fine. It dies with basetags. */
.ux-landing .is-style-ev26-claim h1{
  display:block;
  font-family:var(--serif);
  font-size:var(--t-d-claim);line-height:1.02;
  letter-spacing:var(--disp-track);font-weight:var(--disp-weight);
  color:var(--ink);max-width:29ch;margin:0;
}
.ux-landing .is-style-ev26-claim h1 em{
  font-style:normal;font-weight:var(--disp-weight);color:var(--accent);
}
.ux-landing .is-style-ev26-claim p:not(.ev26-eyebrow):not(.ux-kind){
  font-size:var(--t-lead);line-height:1.62;color:var(--muted);
  max-width:60ch;margin:28px 0 0;
}
.ux-landing .is-style-ev26-claim .wp-block-buttons{margin-top:34px}

/* ── buttons ─────────────────────────────────────────
 * Core buttons block, pill-shaped like every other control in the theme.
 * `is-style-outline` is a CORE button style, so the ghost variant needs no new
 * block registration. */
.ux-landing .wp-block-buttons{display:flex;flex-wrap:wrap;gap:12px}
.ux-landing .wp-block-button__link{
  display:inline-flex;align-items:center;
  background:var(--ink);color:var(--bg);border:1px solid var(--ink);
  border-radius:999px;padding:13px 24px;
  font-family:var(--sans);font-size:var(--t-meta);font-weight:700;letter-spacing:var(--tr-ui);
  transition:transform var(--fast) var(--ease),background var(--fast) var(--ease);
}
.ux-landing .wp-block-button__link:hover{transform:translateY(-1px)}
.ux-landing .wp-block-button.is-style-outline .wp-block-button__link{
  background:transparent;color:var(--ink);border-color:var(--line-strong);
}
.ux-landing .wp-block-button.is-style-outline .wp-block-button__link:hover{
  border-color:var(--ink);
}
.ux-landing .wp-block-button__link:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

/* ── the figures ─────────────────────────────────────
 * The load-bearing section, and the only one with a rule above it: it is the
 * moment the page stops claiming and starts evidencing, which is exactly the
 * confusion a hairline exists to prevent.
 *
 * Each figure is a before → after PAIR rather than a lone percentage. Showing
 * the base alongside the outcome is the honest form and it pre-empts the first
 * follow-up question a hiring manager asks. */
.ux-landing .is-style-ev26-figures{
  border-top:1px solid var(--line);
  padding-top:30px;
}
.ux-landing .is-style-ev26-figures .ev26-eyebrow{color:var(--faint);margin-bottom:30px}
.ux-landing .is-style-ev26-figures .wp-block-columns{gap:40px;margin-bottom:0}
.ux-landing .ev26-figure{
  font-family:var(--sans);
  font-size:var(--t-d-card);font-weight:700;
  letter-spacing:var(--tr-stat);line-height:1;color:var(--faint);
  margin:0;
}
/* The arrow is an <em> — a native inline format, so Gutenberg round-trips it
   without ever offering block recovery. It is deliberately not italic. */
.ux-landing .ev26-figure em{
  font-style:normal;color:var(--line-strong);
  padding:0 .18em;font-size:.66em;vertical-align:.06em;
}
/* The outcome value is a <strong> — also native. Colour marks the result, not
   the hierarchy; the hierarchy is already carried by size and weight. */
/* background:none clears basetags.css `:where(p) strong{background-color:#ffe70099}`
   -- a hardcoded yellow highlighter that lands squarely on the outcome value
   of every figure if it is not turned off here. */
.ux-landing .ev26-figure strong{font-weight:700;color:var(--ink);background:none}
.ux-landing .is-style-ev26-figures .ev26-figure + p{
  margin:12px 0 0;font-size:var(--t-meta);line-height:1.55;
  color:var(--text);max-width:30ch;
}
.ux-landing .is-style-ev26-figures .ev26-figure + p strong{
  font-weight:600;color:var(--ink);background:none;
}

/* The denominator. Raised onto --paper so it reads as a definition the page is
   volunteering, not a disclaimer it is hiding. Body size, never smaller. */
.ux-landing .ev26-denominator{
  background:var(--paper);border-radius:var(--r-m);
  box-shadow:var(--raise);
  padding:28px 32px;
  margin:34px 0 0;
  font-size:var(--t-body);line-height:1.62;color:var(--text);
}
/* 82ch keeps the definition at a readable measure inside a 1032px section --
   the full width would run past 100 characters, which is where a paragraph
   this important starts losing people. */
.ux-landing .ev26-denominator{max-width:82ch}

.ux-landing .ev26-denominator strong{
  color:var(--ink);font-weight:600;
  background:linear-gradient(transparent 62%,var(--accent-soft) 62%);
}

/* ── section heads ───────────────────────────────────
 * A core group block carrying a block style, so /ux/ needs no custom block.
 * It no longer MIRRORS .shead — v26-components.css names this class in the
 * same rule, so it IS .shead, with only its own layout stated below. */
.ux-landing .is-style-ev26-shead{
  display:flex;align-items:baseline;gap:18px;flex-wrap:wrap;
  margin-bottom:48px;
}
/* The heading's type is the shared group-header rung — v26-components.css
   matches .is-style-ev26-shead alongside .shead, so this block style is the
   same component, not a copy of it (#1450). */
/* The deck beside it. 15/--muted, up from 13.5/--faint (#1467): after #1450
   raised the group header to --shead-size (26px at 1440), a 13.5px faint line
   baseline-aligned next to it stopped reading as the section's deck and
   started reading as a caption that had come unmoored from something else --
   which is exactly the four-instance complaint #1467 filed against this page.
   15px is still unmistakably subordinate to 26px sans-bold and still carries
   no heading weight, so the ladder is untouched; it is only the difference
   between a deck and fine print. One rule, so all four /ux/ sheads move
   together -- a per-section exception here is how the page would end up with
   two kinds of deck. */
/* 28ch (#1493). The deck sat on ONE long line running most of the way across
   the measure, which read as a subtitle bolted onto the heading rather than a
   caption sitting beside it. Held to 28ch it sets as a compact two-line block
   next to the h2 — two lines at 1440 for the "How" deck, which is the longest
   of the four; the three short ones still fit on one. The wording tightened at
   the same time ("Three moves, same order, whatever the problem is."), so the
   break is the copy's, not a squeeze. */
.ux-landing .is-style-ev26-shead p{
  margin:0;font-size:var(--t-body);color:var(--muted);max-width:28ch;
}

/* ── method ──────────────────────────────────────────
 * Three moves, in order (v2, #1468). The counter still comes from CSS so the
 * author never types "01" and the sequence can never fall out of step with the
 * markup — but the counter is now the SECTION'S ORDERING SIGNAL rather than a
 * caption on it, so it is set at display size.
 *
 * WHY A NUMERAL AND NOT A DRAWN TRACK. Eric chose oversized numerals over a
 * hairline track joining three nodes. The honest risk of that choice is that
 * three big digits read as three ornaments that happen to contain numbers
 * instead of as a count, and then the section has lost its ordering signal
 * rather than strengthened it. Four things are doing the work that stops that,
 * and none of them is size:
 *
 *   1. LEADING ZEROS (decimal-leading-zero). "01 02 03" is a series notation;
 *      "1 2 3" at 92px is three shapes. The zero is what says "of a set".
 *   2. TABULAR, LINING FIGURES. Every numeral occupies the identical advance,
 *      so the three marks are the same width to the pixel and the eye reads
 *      them as drawn from one series rather than as three separate objects.
 *   3. A SHARED TOP EDGE. The mark is in normal flow at the head of each
 *      column, not absolutely placed, so all three cap-heights line up by
 *      construction at every width — the horizontal read across the row is
 *      what turns three marks into a count.
 *   4. ONE GLYPH CHANGES. Because 1–3 hold, the only thing that differs
 *      left-to-right is the final digit, and an incrementing digit against an
 *      otherwise identical mark is a counter, which is precisely the reading
 *      the rejected track would have supplied.
 *
 * COLOUR IS DECORATION HERE, NOT HIERARCHY. The mark is --accent, but it is
 * not what separates a heading level from another heading level: the h2/h3/body
 * ladder below is family + size + weight exactly as before, and the numerals
 * would still read as an ordered set rendered in --ink. Removing the colour
 * would cost the section warmth, not its structure. Strength is dialled with a
 * color-mix against the accent rather than a second hue, so it holds in dark
 * (where --accent is the light blue) with no theme-specific rule.
 *
 * CONTRAST. The marks sit in the tail of the section wash (#1458), which on
 * /ux/ peaks at --wash-a 20% at the top of the document and is already well
 * under 2% alpha by the time it reaches this section. The mark is therefore
 * effectively on --bg in both themes, and at 78% accent it measures far past
 * the 3:1 a graphic object needs in both. It is deliberately NOT full-strength
 * accent: three 92px saturated blue marks out-shout "How", which is the one
 * thing on the row that must stay the section's title. */
.ux-landing .is-style-ev26-method .wp-block-columns{counter-reset:ev26-move;gap:44px;margin-bottom:0}
.ux-landing .is-style-ev26-method .wp-block-column{
  counter-increment:ev26-move;position:relative;padding-top:0;
}
.ux-landing .is-style-ev26-method .wp-block-column::before{
  content:counter(ev26-move,decimal-leading-zero);
  display:block;
  font-family:var(--sans);
  /* 7.2vw is the growth rate, not the value: it puts the mark at its 92px cap
     from ~1280 up and floors it at 58px, which is the largest "01" that still
     leaves the 375 column at its 331px measure with room to spare. */
  font-size:var(--t-d-numeral);
  font-weight:700;
  line-height:.82;
  letter-spacing:-.045em;
  font-variant-numeric:tabular-nums lining-nums;
  font-feature-settings:"tnum" 1,"lnum" 1; /* older Safari, same intent */
  color:color-mix(in oklab,var(--accent) 78%,transparent);
  /* The zero is a round glyph; its left extreme is inside its sidebearing, so
     the mark is pulled out by a hair to sit on the same optical edge as the
     stems of the heading beneath it. */
  margin:0 0 14px -.055em;
}
/* 20px, down from 23. The group header above is --shead-size (26px at 1440),
   and 23 against 26 was three pixels of separation carrying a whole level of
   the ladder (#1467's second note). The numeral now supplies the column's
   visual weight, so the move title no longer has to compete with the section
   title to be found — dropping it to 20 buys real separation and costs the
   heading nothing. Family still differs (serif under a sans header), so the
   two levels are distinguished twice over. */
.ux-landing .is-style-ev26-method h3{
  font-family:var(--serif);font-size:var(--t-lead);line-height:1.25;
  letter-spacing:var(--tr-lead);font-weight:600;color:var(--ink);margin:0 0 10px;
}
/* Scoped to the COLUMN, not to the whole method group. As `.is-style-ev26-method
   p` this rule was (0,3,1) and silently beat every (0,2,0) declaration on the
   "Lately" strip that now lives in the same group -- it ate the strip's 56px
   top margin and its --text colour, and the first render came back with the
   panel jammed 15px under the columns. Rendered and caught; do not widen this
   selector back out. */
.ux-landing .is-style-ev26-method .wp-block-column p{
  margin:0;font-size:var(--t-body);line-height:1.65;color:var(--muted);
}
/* Two of the three move titles run to two lines and one does not. Reserving
   two lines keeps the three body paragraphs on a shared top edge, which is the
   whole point of setting them as a row. */
@media (min-width:782px){
  .ux-landing .is-style-ev26-method h3{min-height:2.5em}
}

/* ── the work ───────────────────────────────────
 * A flagship, then four, all five rendered from the posts (#1443 — see the
 * long note in page-ux.php). Separation is a lift off the ground and space;
 * there is not a drawn box anywhere in this section.
 *
 * SURFACE (#1421). The fill is var(--paper), which is no longer a colour but a
 * translucent LIFT resolved against whatever ground the page is painting, and
 * the cast shadow is var(--raise). Both halves are required: a translucent fill
 * with no shadow reads as a wash painted ON the ground rather than a card
 * lifted off it, which is exactly how these panels read before this pass — the
 * #1421 agent flagged the ux panels as inheriting the fill and missing the
 * shadow. Fixed here for all three raised surfaces on the page.
 *
 * HIT AREA. Each card is position:relative and the title's <a> throws a
 * ::after over the whole card. So: one link, one accessible name (the title),
 * the entire card clickable, and hover/focus driven from the card. Nothing is
 * wrapped in an anchor.
 */
/* #1500 — Eric: "use the same card styling on the UX Case Studies that you're
 * using on the Home page and Lab grids." That is `.cell` (v26-components.css):
 * flat until touched, bottom-only radius so the accent bar sits flush at the
 * very top edge, and the raise is background+shadow only, no lift. This card
 * carried its own permanent panel (var(--paper) at rest, translateY on hover)
 * — the one surface on the site still doing elevation differently. */
.ux-landing .ev26-workcard{
  position:relative;
  /* basetags.css (loaded after this file) sets `section,article{padding:20px 0;
     margin:0 0 50px}` for the ericville25 cascade. The card is an <article>, so
     without this reset it carries a 20px inset that stopped the flagship's
     picture short of the card's own edges, plus a 50px bottom margin stacking
     on the grid's 20px gap. Both were visible in the first render.
     #1500 — Eric: "the indentation on the text vs images is off between the
     Home and UX pages... aim for the Home version." The image sat full-bleed
     to the card's own edges while the title/deck below it were padded in
     26px — the two zones didn't share a left edge, which is what read as
     misaligned on a phone (Home's `.cell` never had this problem: ONE
     padding on the whole card, image included, per the #1500 pass above).
     padding:0 -> 22px 22px 26px, matching .cell exactly, on the base rule so
     both the grid cards and — below 782px, where the lead card falls back to
     these base styles rather than its own row-layout override — the
     flagship card get it too. */
  padding:22px 22px 26px;margin:0;
  border-radius:0 0 var(--r-m) var(--r-m);
  overflow:hidden;
  display:flex;flex-direction:column;
  transition:background var(--med) var(--ease),box-shadow var(--med) var(--ease),transform .28s var(--spring);
}
/* :focus-within, not just :hover — the keyboard reaches the card through the
   title link, and the card must show the same state the mouse gets. */
.ux-landing .ev26-workcard:hover,
.ux-landing .ev26-workcard:focus-within{
  background:var(--paper);
  box-shadow:var(--raise);
}
/* Press state, matching `.cell:active` — :active on the card is correct even
   though the click target is the nested stretched-link <a>: CSS propagates
   :active up the ancestor chain for the duration of the press. */
.ux-landing .ev26-workcard:active{transform:scale(.98);transition-duration:.08s}
/* The accent-bar wipe, identical to `.cell::after` — same selector name, same
   timing, same token, so the two components read as one family. */
.ux-landing .ev26-workcard::after{
  content:"";position:absolute;left:0;right:0;top:0;height:2px;
  background:var(--accent);transform:scaleX(0);transform-origin:left;
  transition:transform var(--med) var(--ease);
}
.ux-landing .ev26-workcard:hover::after,
.ux-landing .ev26-workcard:focus-within::after{transform:scaleX(1)}
/* The stretched link. inset:0 rather than a wrapping anchor: the accessible
   name stays the title, and a link added inside the card later is still
   reachable by giving it position:relative. */
.ux-landing .ev26-workcard__title a::after{
  content:"";position:absolute;inset:0;z-index:1;
  border-radius:inherit;
}
/* The focus ring belongs to the card, not to the invisible overlay — outlining
   the <a> would draw a rectangle around the title text only, which is not what
   is being activated. */
.ux-landing .ev26-workcard__title a:focus-visible{outline:none}
.ux-landing .ev26-workcard:focus-within{
  outline:2px solid var(--accent);outline-offset:3px;
}

/* The media well is a RECESS, so an image that has not painted yet is a dent in
   the card rather than a white hole. Fixed ratio so five different source
   crops still line the row up. */
.ux-landing .ev26-workcard__media{
  background:var(--sunken);
  aspect-ratio:16/9;overflow:hidden;
  /* Was full-bleed to the card's own edge; now inset by the card's own
     padding like every other image on the site, with the same small-radius
     object treatment `.cell.feat`'s image already uses. margin-bottom
     mirrors `.cell figure{margin:14px 0 16px}` — the gap to the title. */
  border-radius:var(--r-s);margin:0 0 16px;
}
/* #1500 — Eric: match the grayscale treatment every other grid on the site
 * uses (`.cell figure img` in v26-components.css, and the bio/feature photos
 * in v26-home.css): grayscale at rest, full colour on hover. These cards were
 * the one place left running source colour. */
.ux-landing .ev26-workcard__media img{
  display:block;width:100%;height:100%;
  object-fit:cover;object-position:center;
  filter:grayscale(1) contrast(1.06);
  transition:transform var(--slow) var(--ease),filter var(--slow) var(--ease);
}
.ux-landing .ev26-workcard:hover .ev26-workcard__media img{transform:scale(1.03);filter:grayscale(0) contrast(1)}

.ux-landing .ev26-workcard__text{
  display:flex;flex-direction:column;
  /* Horizontal inset now comes from the card's own padding above, matching
     Home's .cell (figure and text share one edge, not two different ones). */
  padding:0;
}
.ux-landing .ev26-workcard .ev26-meta{
  order:-1;
  font-family:var(--sans);font-size:var(--t-label);font-weight:700;
  letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--faint);
  margin:0 0 10px;
}
.ux-landing .ev26-workcard__title{
  font-family:var(--serif);font-size:var(--t-lead);line-height:1.24;
  letter-spacing:var(--tr-lead);font-weight:600;color:var(--ink);margin:0;
}
.ux-landing .ev26-workcard__title a{
  color:inherit;transition:color var(--fast) var(--ease);
}
.ux-landing .ev26-workcard:hover .ev26-workcard__title a{color:var(--accent)}
.ux-landing .ev26-workcard__deck{
  margin:10px 0 0;font-size:var(--t-meta);line-height:1.6;color:var(--muted);
}

/* ─ the flagship ─────────────────────────────────────────
 * Same card, more room: picture beside the words instead of above them, and
 * the type ladder steps up. It is one component with one modifier, not a
 * second implementation. */
@media (min-width:782px){
  /* #1500 — Eric: "it should use the same styling as the top Essay card."
     That's `.cell.feat` (v26-lab.css): a flat, unbordered card with PADDING
     around everything, where the image is its own small-radius (--r-s)
     object inset inside that padding — not a panel with a full-bleed image
     inside a bigger radius, which is what this still was. */
  .ux-landing .ev26-workcard--lead{
    /* padding/border-radius now come from the base .ev26-workcard rule —
       identical values, no longer restated here. */
    flex-direction:row;align-items:stretch;gap:28px;
  }
  .ux-landing .ev26-workcard--lead .ev26-workcard__media{
    flex:0 0 46%;aspect-ratio:auto;
    /* Beside the text now, not above it — the base rule's 16px
       margin-bottom (for the stacked layout) would just be dead space
       under the image in a row. gap:28px above already separates them. */
    margin-bottom:0;
  }
  .ux-landing .ev26-workcard--lead .ev26-workcard__text{
    flex:1 1 auto;justify-content:center;
    padding:4px 0;
  }
}
.ux-landing .ev26-workcard--lead .ev26-meta{color:var(--accent);margin-bottom:16px}
.ux-landing .ev26-workcard--lead .ev26-workcard__title{
  font-size:var(--t-d-card);line-height:1.08;
  letter-spacing:var(--tr-head);max-width:20ch;
}
.ux-landing .ev26-workcard--lead .ev26-workcard__deck{
  margin-top:18px;font-size:var(--t-body);line-height:1.65;max-width:52ch;
}
/* The "read on" affordance, kept from the old lead card. It is a SPAN now, not
   a link: the card is already the link, and a second anchor under the stretched
   overlay would be dead. aria-hidden in the markup, so it is a picture of a
   link for the eye and nothing at all for a screen reader. */
.ux-landing .ev26-cue{
  display:inline-flex;align-items:center;gap:10px;
  margin-top:24px;
  font-family:var(--sans);font-size:var(--t-meta);font-weight:700;color:var(--ink);
  transition:color var(--fast) var(--ease);
}
.ux-landing .ev26-cue::after{
  content:"";width:18px;height:1.5px;background:currentColor;
  transition:width var(--med) var(--ease);
}
.ux-landing .ev26-workcard:hover .ev26-cue{color:var(--accent)}
.ux-landing .ev26-workcard:hover .ev26-cue::after{width:32px}

/* ─ the other four ───────────────────────────────────── */
/* 32px, up from 20 (#1493). These cards are lifted surfaces with no drawn
   border, so the ONLY thing saying "two objects" rather than "one panel with a
   seam" is the ground showing between them. At 20 the four grid cards read as a
   slab; at 32 — a shade over the 26px the card pads its own text by — each card
   is unmistakably its own. The gap is the same figure in both axes so the grid
   stays square, and the 375 breakpoint keeps its tighter 14. */
.ux-landing .ev26-work{display:flex;flex-direction:column;gap:32px}
.ux-landing .ev26-work__grid{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:32px;
}
/* A card with no featured image is a text-only card, not an empty well. The
   deck carries the extra room the picture would have taken, so the row still
   bottoms out level. */
.ux-landing .ev26-workcard.is-textonly .ev26-workcard__text{padding-top:28px}

/* One quiet line for the two essays, so they are reachable without competing
   with the case studies. */
.ux-landing .ev26-alsoread{
  margin:24px 0 0;font-size:var(--t-meta);line-height:1.6;color:var(--faint);
}
.ux-landing .ev26-alsoread a{
  color:var(--accent);
  box-shadow:inset 0 -1.5px 0 color-mix(in oklab,var(--accent) 35%,transparent);
}
.ux-landing .ev26-alsoread a:hover{box-shadow:inset 0 -1.5px 0 var(--accent)}
.ux-landing .ev26-alsoread em{font-style:italic}

/* ── the AI trail ────────────────────────────────────
 * A core list, laid out against a date axis. The single vertical hairline is
 * the second and last rule on the page: it separates the axis from the prose,
 * which is precisely the confusion a rule is for. */
.ux-landing .is-style-ev26-trail ul{
  list-style:none;margin:0;padding:0;position:relative;
}
/* THE CONNECTOR IS DRAWN PER ENTRY, NOT ONCE DOWN THE LIST (#1499).
 * It used to be a single `ul::before` running `top:8px` to `bottom:8px`, which
 * meant it carried on past the final node into the empty tail of the last <li>
 * — a line pointing at nothing, which reads as a missing entry. Segmenting it
 * onto each <li> as a 1px background gradient lets the LAST segment stop at its
 * own dot (25px = the dot's top 22px plus half its 7px), so the axis ends
 * exactly where the trail does. A background rather than a third pseudo-element
 * because the li already spends ::before on the dot and ::after on the pulse. */
.ux-landing .is-style-ev26-trail li{
  position:relative;
  padding:14px 0 14px 112px;
  margin:0;
  font-size:var(--t-body);line-height:1.62;color:var(--text);max-width:74ch;
  background:linear-gradient(var(--line),var(--line)) no-repeat 82px 0/1px 100%;
}
/* The head of the axis keeps the old 8px inset above the first dot. */
.ux-landing .is-style-ev26-trail li:first-child{
  background-position:82px 8px;background-size:1px calc(100% - 8px);
}
/* `> strong:first-child` and not `strong`: each entry now carries a SECOND
   strong — its name (#1493) — and the year is the one that leaves the flow for
   the date axis. Scoping to the first child means the name is untouched by the
   absolute placement rather than fighting it back with an override. */
.ux-landing .is-style-ev26-trail li > strong:first-child{
  position:absolute;left:0;top:16px;
  font-family:var(--sans);font-size:var(--t-label);font-weight:700;
  letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--accent);
}
/* The entry's NAME (#1493). Every node used to be a year and a paragraph, so
   the list could only be read one sentence at a time; a named node can be
   scanned. It is a block, so the name owns its own line above the prose and the
   eight names stack into a column the eye can run down — sans against the
   serif-free body text, --ink against --text, which is the same one-rung lift
   the card titles make over their decks. */
.ux-landing .is-style-ev26-trail li .ev26-trail-name{
  display:block;
  font-family:var(--sans);font-size:var(--t-meta);font-weight:700;
  letter-spacing:var(--tr-ui);color:var(--ink);
  margin:0 0 4px;
}
/* A named node that HAS a piece of work behind it links to it (#1499). Not
   every node does — the ones with no published target stay plain text, so the
   underline is a reliable signal that there is something to read rather than
   decoration applied to all eight. Same inset-shadow underline the "Also
   published" line uses, so a link looks like a link everywhere on this page;
   colour stays --ink so the name keeps its rung and the accent is spent on the
   rule, not the word. */
.ux-landing .is-style-ev26-trail li .ev26-trail-name a{
  color:inherit;text-decoration:none;
  box-shadow:inset 0 -1.5px 0 color-mix(in oklab,var(--accent) 35%,transparent);
}
.ux-landing .is-style-ev26-trail li .ev26-trail-name a:hover,
.ux-landing .is-style-ev26-trail li .ev26-trail-name a:focus-visible{
  color:var(--accent);box-shadow:inset 0 -1.5px 0 var(--accent);
}
/* A dot on the axis, so the eye can count the entries. */
.ux-landing .is-style-ev26-trail li::before{
  content:"";position:absolute;left:79px;top:22px;
  width:7px;height:7px;border-radius:999px;
  background:var(--bg);box-shadow:0 0 0 1px var(--line-strong);
}
/* The axis stops here — see the connector note above. */
.ux-landing .is-style-ev26-trail li:last-child{
  color:var(--ink);
  background-size:1px 25px;
}
.ux-landing .is-style-ev26-trail li:last-child::before{
  background:var(--accent);box-shadow:0 0 0 1px var(--accent);
  /* Above the halo below, which paints after it in source order. */
  z-index:1;
}

/* The bottom tip pulses, because the journey has not stopped (#1438).
 *
 * A SECOND dot, sitting exactly under the last node, scaling out and fading —
 * a ring leaving the node rather than the node itself throbbing, so the dot the
 * eye counts the entries by stays crisp and still at 7px.
 *
 * WHAT THIS IS NOT, deliberately. Not a filter, and not an animated gradient.
 * This repo has removed two motion features after measured jank — an 8s
 * infinite gradient on a blended full-viewport layer, and a transitioned
 * backdrop-filter on the sticky header — and unlike the hero's 520ms swap this
 * thing is on screen for as long as the section is. So it is the cheapest form
 * available: `transform` and `opacity` on one 7px pseudo-element, both
 * compositor properties, no filter, no blend mode, no `will-change`, no box
 * that ever changes size. Nothing reflows and nothing repaints outside 18px.
 *
 * The dot is `background:var(--accent)`, so it is blue on /ux/ and light blue
 * in the dark theme with no second declaration. */
@keyframes ev26-trail-pulse{
  0%   {transform:scale(1);opacity:.5}
  70%  {transform:scale(2.6);opacity:0}
  100% {transform:scale(2.6);opacity:0}
}
.ux-landing .is-style-ev26-trail li:last-child::after{
  content:"";position:absolute;left:79px;top:22px;
  width:7px;height:7px;border-radius:999px;
  background:var(--accent);
  animation:ev26-trail-pulse 2.8s var(--ease) infinite;
}

/* ── the endorsements ────────────────────────────────
 * Several quotes, ONE at a time, rotating (#1442 — see js/quotes.js).
 *
 * Receipts used to sit above this: a dense two-column list of verifiable facts.
 * Eric cut it in favour of more voices, so its styles are gone with it rather
 * than left here to rot.
 *
 * THE STACK. The group is a one-cell grid and every blockquote is
 * `grid-area:1/1`, so all of them occupy the same space and the cell is as tall
 * as the longest quote. Nothing below the section can move when the words
 * change — the same guarantee the hero headline makes, for the same reason.
 *
 * THE ATTRIBUTION IS PINNED. Each blockquote is itself a `1fr auto` grid
 * stretched to the full cell, so the quote sits at the top of the box and the
 * cite sits on the bottom edge of it — the same bottom edge for all four. If
 * the cite simply followed its paragraph it would jump up and down by two lines
 * as the quotes changed length, which reads as the name being unsure which
 * quote it belongs to. It always belongs to the one above it: the cite is a
 * CHILD of its own blockquote and fades with it as one element.
 *
 * WITHOUT JS, OR WITHOUT MOTION, THIS IS A SINGLE STATIC QUOTE. The stylesheet
 * shows the first blockquote unconditionally; only when quotes.js takes over
 * does it add `is-live`, which hands control to `.is-on`. So JS off, JS broken,
 * or prefers-reduced-motion all land on exactly what the page had before this
 * ticket: one endorsement, no movement. The inactive quotes are
 * `visibility:hidden`, which takes them out of the accessibility tree as well
 * as off the screen — the aria-hidden quotes.js adds is belt and braces. */
/* THE SURFACE (#1493). Until now this section was words on the page ground with
   nothing around them, so the strongest thing on /ux/ — somebody else's
   sentence about Eric — looked like a stray pull-quote the page had failed to
   place. It is the SAME raised surface the work cards and the denominator use
   (#1421): var(--paper), which is a translucent lift rather than a colour, plus
   var(--raise) as the cast shadow. Both halves or neither — a paper fill with
   no shadow is a wash painted on the ground, which is the exact failure that
   pass was filed against. No new pattern, no border, and no second hue: the
   panel resolves against whatever ground the page is painting, so it holds in
   dark with no theme-specific rule. --r-l, not --r-m, because this is one large
   panel rather than a card in a row of them. */
.ux-landing .is-style-ev26-quotes{
  display:grid;
  /* basetags.css `section,article{padding:20px 0;margin:0 0 50px}` does not
     reach a <div>, but the core quote block brings its own border and padding,
     which is cleared per-blockquote below. */
  margin-left:auto;margin-right:auto;
  background:var(--paper);border-radius:var(--r-l);
  box-shadow:var(--raise);
  padding:52px 56px;
}
.ux-landing .is-style-ev26-quotes blockquote{
  grid-area:1/1;
  display:grid;grid-template-rows:1fr auto;
  border:0;padding:0;margin:0;
  visibility:hidden;opacity:0;transform:translateY(8px);
  transition:
    opacity var(--slow) var(--ease),
    transform var(--slow) var(--ease),
    visibility 0s linear var(--slow);
}
/* Pre-init and no-JS: the first quote IS the section. */
.ux-landing .is-style-ev26-quotes blockquote:first-child{
  visibility:visible;opacity:1;transform:none;transition-delay:0s;
}
/* Once JS owns it, `is-on` is the only thing that shows a quote. It carries one
   more class than the :first-child rule above, so it wins on specificity in
   both directions and the order of these two rules does not matter. */
.ux-landing .is-style-ev26-quotes.is-live blockquote:first-child{
  visibility:hidden;opacity:0;transform:translateY(8px);
}
.ux-landing .is-style-ev26-quotes.is-live blockquote.is-on{
  visibility:visible;opacity:1;transform:none;
  transition:
    opacity var(--slow) var(--ease),
    transform var(--slow) var(--ease),
    visibility 0s;
}
/* 32ch, not the single endorsement's 22ch. The cell is as tall as the LONGEST
   quote, so a narrow measure buys three extra lines on the longest one and
   spends them as dead space under every shorter one. Widening the measure by
   ten characters takes the longest quote from five lines to four and closes
   most of that gap — a real trade the single-quote version never had to make. */
.ux-landing .is-style-ev26-quotes blockquote p{
  font-family:var(--serif);
  font-size:var(--t-d-quote);line-height:1.24;letter-spacing:var(--tr-title);
  font-weight:400;color:var(--ink);margin:0;max-width:32ch;
}
.ux-landing .is-style-ev26-quotes blockquote cite{
  align-self:end;
  padding-top:26px;
  font-family:var(--sans);font-style:normal;font-size:var(--t-meta);font-weight:600;
  color:var(--faint);letter-spacing:var(--tr-ui);
}

/* ── the ask ─────────────────────────────────────────*/
.ux-landing .is-style-ev26-cta{
  background:var(--ink);border-radius:var(--r-l);
  padding:64px 52px;
  background-image:var(--grain);background-size:380px;background-blend-mode:soft-light;
}
.ux-landing .is-style-ev26-cta h2{
  font-family:var(--serif);
  font-size:var(--t-d-card);line-height:1.12;letter-spacing:var(--tr-head);
  font-weight:600;color:var(--bg);margin:0;max-width:30ch;
}
.ux-landing .is-style-ev26-cta p{
  color:color-mix(in oklab,var(--bg) 66%,transparent);
  font-size:var(--t-body);line-height:1.6;margin:18px 0 0;max-width:52ch;
}
.ux-landing .is-style-ev26-cta .wp-block-buttons{margin-top:32px}
.ux-landing .is-style-ev26-cta .wp-block-button__link{
  background:var(--bg);color:var(--ink);border-color:var(--bg);
}
.ux-landing .is-style-ev26-cta .wp-block-button.is-style-outline .wp-block-button__link{
  background:transparent;
  color:var(--bg);
  border-color:color-mix(in oklab,var(--bg) 42%,transparent);
}
.ux-landing .is-style-ev26-cta .wp-block-button.is-style-outline .wp-block-button__link:hover{
  border-color:var(--bg);
}

/* Core separator, quietened — basetags gives it a 250px accent bar, which is
   an ericville25 flourish this page does not use. */
.ux-landing .wp-block-separator{
  border:0;height:1px;background:var(--line);
  max-width:none;width:100%;margin:0;opacity:1;border-radius:0;
}

/* ── responsive ──────────────────────────────────────
 * Core stacks wp-block-columns at 781px on its own; these rules handle the
 * things core cannot know about — the section rhythm, the trail's date axis,
 * and the receipts columns. Checked at 1440 / 1024 / 768 / 375. */
/* #1500 — this rule was `@media (max-width:1024px)` with no min-width
 * partner, so it was applying at every width below 1024px, including phones
 * where the lead card is never in the row layout this padding was written
 * for (that only starts at min-width:782px). It was adding a stray 34px of
 * horizontal padding to the flagship card's text on top of the base card's
 * own 22px, which is what actually produced the Home/UX misalignment this
 * ticket reported — not the media/text split fixed above on its own. Scoped
 * to the real row-layout range it was always meant for. */
@media (min-width:782px) and (max-width:1024px){
  .ux-landing .ev26-workcard--lead .ev26-workcard__text{padding:36px 34px}
}
@media (max-width:1024px){
  .ux-landing .is-style-ev26-method .wp-block-columns{gap:32px}
  .ux-landing .is-style-ev26-figures .wp-block-columns{gap:28px}
}
@media (max-width:781px){
  .content.ev26.ux-landing > * + *,
  .ux-landing > .wp-block-group{margin-top:56px}
  .ux-landing{padding-bottom:4px}
  .ux-landing .is-style-ev26-claim{padding-top:48px}
  .ux-landing .is-style-ev26-claim h1{max-width:none}
  .ux-landing .is-style-ev26-claim p:not(.ev26-eyebrow):not(.ux-kind){font-size:var(--t-body);margin-top:22px}
  /* Core's stacked columns collapse the figure trio into a vertical run; give
     each figure its own breathing room and let the label run full width. */
  .ux-landing .is-style-ev26-figures .wp-block-columns{gap:26px}
  /* The 30ch cap is a three-column device. Stacked, the labels get the full
     width -- but capped at a readable measure, not the whole 724px a tablet
     offers. */
  .ux-landing .is-style-ev26-figures .ev26-figure + p{max-width:62ch}
  /* Stacked, the three moves need more air between them than a 30px gap: the
     numeral is the thing that says a new move has started, and it needs room
     above it to be read as a heading rather than as the tail of the paragraph
     before it. */
  .ux-landing .is-style-ev26-method .wp-block-columns{gap:42px}
  .ux-landing .is-style-ev26-method .wp-block-column p{max-width:68ch}
  .ux-landing .is-style-ev26-method h3{max-width:26ch}
  /* Below 782 the flagship is already stacked by the min-width rule above. The
     four keep TWO columns down to 600 — unlike core's wp-block-columns, which
     bails to one at 781. Five full-bleed 16:9 cards in a single column added
     3,000px of scroll to a tablet for no gain in legibility; at 768 a
     two-column card is still ~350px, wider than the same card on a phone. */
  .ux-landing .ev26-work{gap:14px}
  .ux-landing .ev26-work__grid{gap:14px}
  .ux-landing .ev26-workcard--lead .ev26-workcard__title{font-size:var(--t-head)}
  /* The date axis costs 112px of a 375px screen. Below 781 the year becomes a
     label above its line and the rail is dropped — the sequence is still
     legible because the years are in order. */
  .ux-landing .is-style-ev26-trail li{padding:0 0 22px;background:none}
  .ux-landing .is-style-ev26-trail li::before,
  .ux-landing .is-style-ev26-trail li::after{display:none}
  .ux-landing .is-style-ev26-trail li > strong:first-child{
    position:static;display:block;margin-bottom:6px;
  }
  /* The rail goes, but the "still going" signal must not — that is the whole
     point of the last entry. So the last node and its halo come back on the
     phone, moved off the dropped axis to sit in front of the label, which is
     itself now a static block at the top of the item. */
  .ux-landing .is-style-ev26-trail li:last-child::before,
  .ux-landing .is-style-ev26-trail li:last-child::after{
    display:block;left:0;top:6px;
  }
  .ux-landing .is-style-ev26-trail li:last-child > strong:first-child{padding-left:17px}
  .ux-landing .is-style-ev26-cta{padding:40px 28px}
  /* The panel keeps its surface on a phone; only the inset comes in, matching
     the CTA panel above it. */
  .ux-landing .is-style-ev26-quotes{padding:36px 28px}
  .ux-landing .is-style-ev26-quotes blockquote p{max-width:none}
}
@media (max-width:600px){
  .content.ev26.ux-landing > *{padding-left:22px;padding-right:22px}
  /* One column at last: below 600 a two-up card is under 160px of measure. */
  .ux-landing .ev26-work__grid{grid-template-columns:minmax(0,1fr)}
  /* #1500 — the two __text padding overrides that lived here are gone: they
     were compensating for the card having NO padding of its own pre-fix.
     Now that .ev26-workcard carries the same 22px 22px 26px as .cell at
     every width, restating horizontal padding on __text here would just
     double it (44px total). */
  .ux-landing .ev26-denominator,
  .ux-landing .wp-block-buttons{gap:10px}
  .ux-landing .wp-block-button__link{padding:12px 20px}
}

@media (prefers-reduced-motion:reduce){
  .ux-landing .ev26-workcard:hover,
  .ux-landing .ev26-workcard:focus-within{transform:none}
  .ux-landing .ev26-workcard:hover .ev26-workcard__media img{transform:none}
  .ux-landing .wp-block-button__link:hover{transform:none}
  /* The pulse is removed, not paused. `animation:none` alone would leave the
     halo frozen at 100% opacity as a second, larger dot sitting on top of the
     first — a rendering artefact, not a design. The node itself stays: it is
     already the accent-coloured last entry, which is the static half of the
     signal. */
  .ux-landing .is-style-ev26-trail li:last-child::after{display:none}
  /* quotes.js never starts under reduced motion, so `is-live` is never added
     and the first quote simply stays. This kills the cross-fade for the case
     where the preference is turned on mid-session, before quotes.js has torn
     the rotation down. */
  .ux-landing .is-style-ev26-quotes blockquote{transition:none}
}
