/**
 * File: css/changelog-mobile.css
 *
 * Mobile Updates feed (< 992px). The desktop #changelog section and its
 * paginator are hidden below the breakpoint and this block takes over, the
 * same way css/creators-pages.css swaps .creators-mobile in for #our-models.
 *
 * Everything except the one `.cl-mobile { display: none }` line below lives
 * inside @media (max-width: 991.98px), so desktop cannot be reached from here.
 */

.cl-mobile { display: none; }

@media (max-width: 991.98px) {
  /* The desktop tree steps aside. !important is required on the paginator, not
     defensive: js/changelog-pagination.js writes an inline style.display on
     this root, and an inline `display:""` beats a plain stylesheet rule — the
     pager would reappear here on every load, since 17 cards over 4 per page
     always means more than one page. */
  body.changelog-page #changelog,
  body.changelog-page .page-pagination,
  body.changelog-page .page-pagination + hr.divider { display: none !important; }

  .cl-mobile {
    display: block;
    /* Exactly the mobile header's height, so the hero opens flush under it. */
    padding-top: 80px;
    padding-bottom: clamp(56px, 15vw, 76px);
    background: var(--cl-bg);
    color: var(--cl-ink);

    --cl-bg: #FCFBFD;
    --cl-ink: #0C0B2B;
    --cl-ink-2: #45445F;
    --cl-ink-3: #75748C;
    --cl-coral: #FF3B61;
    --cl-violet: #7357F6;
    --cl-line: rgba(12, 11, 43, .08);
    --cl-line-2: rgba(12, 11, 43, .06);
    --cl-radius: 22px;
    --cl-air: 18px;
    /* Flipped to -1 under html.lang-ar so the segmented pill travels the other
       way; transform is physical, direction is not. */
    --cl-dir: 1;
  }

  /* The reference's side gutter is 7.85% of the viewport — 28px at 360, 31px
     at 390, 34px at 430. Wider than the rest of the site on purpose: the whole
     point of this page is air. */
  .cl-mobile__inner {
    width: 100%;
    max-width: 470px;
    margin: 0 auto;
    padding-inline: clamp(24px, 7.85vw, 34px);
  }

  /* --- hero -------------------------------------------------------------- */

  .cl-hero { padding-top: clamp(22px, 6.5vw, 30px); }

  .cl-hero__eyebrow {
    margin: 0 0 clamp(10px, 2.8vw, 14px);
    color: var(--cl-coral);
    font-size: 10.5px;
    font-weight: 800;
    letter-spacing: .13em;
    line-height: 1;
    text-transform: uppercase;
  }

  /* Set from the reference: cap height is 0.76 of the side gutter, which lands
     the display size at ~8.4vw. Uppercase, one weight above the card titles,
     tracking pulled in hard so "WHAT'S NEW." holds one line at 360. */
  .cl-hero__title {
    margin: 0;
    color: var(--cl-ink);
    font-size: clamp(30px, 8.4vw, 38px);
    font-weight: 800;
    letter-spacing: -.03em;
    line-height: .96;
    text-transform: uppercase;
    text-wrap: balance;
  }

  .cl-hero__dot { color: var(--cl-coral); }

  .cl-hero__lede {
    /* Measure in em so the two lines survive a language change instead of
       spilling to three. */
    max-width: 23em;
    margin: clamp(13px, 3.6vw, 17px) 0 0;
    color: var(--cl-ink-2);
    font-size: clamp(13.5px, 3.6vw, 15px);
    line-height: 1.5;
  }

  /* No reserved height here on purpose: this line grows to two lines in ru /
     th / vi and changes on every filter tap, but withAnchor() restores the
     reader's position from the anchor card's own viewport offset, which absorbs
     any height change above the feed. Reserving two lines would only leave a
     hole under a one-line row. */
  .cl-hero__latest {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 7px 10px;
    margin: clamp(18px, 5vw, 24px) 0 0;
  }

  .cl-hero__latest-tag,
  .cl-hero__latest-platform {
    padding: 5px 12px 6px;
    border-radius: 999px;
    font-size: 12.5px;
    font-weight: 700;
    line-height: 1.15;
  }

  .cl-hero__latest-tag { background: rgba(255, 59, 97, .1); color: var(--cl-coral); }

  .cl-hero__latest-platform {
    background: rgba(12, 11, 43, .06);
    color: var(--cl-ink);
  }

  .cl-hero__latest-version {
    color: var(--cl-coral);
    font-size: clamp(20px, 5.6vw, 25px);
    font-weight: 800;
    letter-spacing: -.02em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
  }

  .cl-hero__latest-date {
    color: var(--cl-ink-3);
    font-size: 13.5px;
    line-height: 1.2;
  }

  /* --- segmented control ------------------------------------------------- */

  /* Three equal columns, so the pill has one constant width and only ever
     translates. Nothing is measured, which means nothing can desync when a
     Thai label is three times the width of "All", and RTL needs only the
     --cl-dir flip. */
  .cl-mobile__filter {
    position: relative;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    margin-top: clamp(20px, 5.5vw, 26px);
    padding: 5px;
    border: 1px solid var(--cl-line);
    border-radius: 999px;
    background: #fff;
    box-shadow: 0 2px 10px rgba(12, 11, 43, .04);
    isolation: isolate;
  }

  .cl-mobile__filter__pill {
    position: absolute;
    top: 5px;
    inset-inline-start: 5px;
    z-index: 0;
    width: calc((100% - 10px) / 3);
    height: calc(100% - 10px);
    border-radius: 999px;
    background: linear-gradient(135deg, #FF4E70 0%, #FF3B61 55%, #F92C58 100%);
    box-shadow: 0 6px 16px rgba(255, 59, 97, .3);
    transform: translate3d(0, 0, 0);
    pointer-events: none;
  }

  /* 100% of the pill's own width is exactly one segment, because the segments
     are thirds of the same track. */
  .cl-mobile__filter[data-filter="ios"] .cl-mobile__filter__pill {
    transform: translate3d(calc(100% * var(--cl-dir)), 0, 0);
  }

  .cl-mobile__filter[data-filter="android"] .cl-mobile__filter__pill {
    transform: translate3d(calc(200% * var(--cl-dir)), 0, 0);
  }

  /* The transition is gated behind is-ready, added two frames after mount, so
     arriving at ?platform=android paints the pill already in place instead of
     sliding it in from the first segment. */
  .cl-mobile__filter.is-ready .cl-mobile__filter__pill {
    transition: transform 280ms cubic-bezier(.22, .61, .36, 1);
  }

  .cl-mobile__filter__btn {
    position: relative;
    z-index: 1;
    min-height: clamp(42px, 11.5vw, 48px);
    padding: 0 6px;
    border: 0;
    border-radius: 999px;
    background: none;
    color: var(--cl-ink);
    font-family: inherit;
    font-size: clamp(13px, 3.5vw, 14.5px);
    font-weight: 700;
    letter-spacing: -.005em;
    white-space: nowrap;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
    /* Cross-fades while the pill travels, so it never arrives under dark text
       or leaves white text behind on the plain track. */
    transition: color 220ms cubic-bezier(.22, .61, .36, 1);
  }

  .cl-mobile__filter__btn[aria-selected="true"] { color: #fff; }

  .cl-mobile__filter__btn:focus-visible {
    outline: 2px solid var(--cl-coral);
    outline-offset: 3px;
  }

  /* --- the feed ---------------------------------------------------------- */

  .cl-mobile__feed {
    margin-top: clamp(22px, 6vw, 28px);
    /* The anchor helper in the module is the mechanism that keeps the page
       still across a filter tap; the browser's own anchoring is the net. */
    overflow-anchor: auto;
  }

  .cl-mobile__list {
    display: grid;
    gap: clamp(16px, 4.4vw, 20px);
  }

  /* Filtering is display, not height. The `hidden` attribute alone would not
     be enough — an author `display` on .cl-card beats the UA sheet's [hidden]
     rule — so it is spelled out. */
  .cl-mobile__list .cl-card[hidden] { display: none !important; }

  .cl-card {
    position: relative;
    overflow: hidden;
    border: 1px solid var(--cl-line);
    border-radius: var(--cl-radius);
    background: #fff;
    box-shadow: 0 1px 2px rgba(12, 11, 43, .03), 0 10px 26px -14px rgba(12, 11, 43, .14);
    isolation: isolate;
  }

  .cl-card[data-platform="ios"] {
    --cl-accent: #FF3B61;
    --cl-accent-soft: rgba(255, 59, 97, .1);
  }

  .cl-card[data-platform="android"] {
    --cl-accent: #7357F6;
    --cl-accent-soft: rgba(115, 87, 246, .1);
  }

  /* The upper block: copy on the left, the colour panel in the slot the phone
     mockup used to hold — the right 43.5% of the card, as in the reference. */
  .cl-card__main {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 38%;
    align-items: stretch;
  }

  .cl-card__copy {
    padding: clamp(15px, 4.1vw, 18px);
    padding-inline-end: clamp(10px, 3vw, 13px);
  }

  .cl-card__date {
    display: block;
    color: var(--cl-ink-3);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .07em;
    line-height: 1;
    text-transform: uppercase;
  }

  .cl-card__idline {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 9px;
    margin-top: clamp(8px, 2.4vw, 11px);
  }

  .cl-card__version {
    color: var(--cl-ink);
    font-size: clamp(21px, 5.9vw, 26px);
    font-weight: 800;
    letter-spacing: -.03em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
  }

  .cl-card__pill {
    padding: 4px 10px 5px;
    border-radius: 999px;
    background: var(--cl-accent-soft);
    color: var(--cl-accent);
    font-size: 11px;
    font-weight: 700;
    line-height: 1.15;
  }

  .cl-card__type {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-top: clamp(11px, 3.2vw, 14px);
    color: var(--cl-accent);
    font-size: 10.5px;
    font-weight: 800;
    letter-spacing: .08em;
    line-height: 1;
    text-transform: uppercase;
  }

  .cl-card__type-badge {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 19px;
    height: 19px;
    border-radius: 50%;
    background: var(--cl-accent-soft);
  }

  .cl-card__type-badge svg { display: block; width: 11px; height: 11px; }

  .cl-card__title {
    margin: clamp(10px, 3vw, 13px) 0 0;
    color: var(--cl-ink);
    font-size: clamp(17px, 4.6vw, 20px);
    font-weight: 800;
    letter-spacing: -.028em;
    line-height: 1.13;
    text-wrap: balance;
  }

  .cl-card__summary {
    margin: clamp(7px, 2.2vw, 10px) 0 0;
    color: var(--cl-ink-2);
    font-size: clamp(12.5px, 3.3vw, 13.5px);
    line-height: 1.46;
  }

  /* --- the colour panel -------------------------------------------------- */

  /* No image, no mockup: a tinted field, two soft circles and a very large
     translucent numeral. The circles are gradients on pseudo-elements, so the
     page adds no asset of any kind. Static art — nothing here animates. */
  .cl-card__panel {
    position: relative;
    overflow: hidden;
    container-type: inline-size;
    background: linear-gradient(150deg, #FBFAFC 0%, #F3F1F7 100%);
  }

  .cl-card__panel::before,
  .cl-card__panel::after {
    content: "";
    position: absolute;
    border-radius: 50%;
    pointer-events: none;
  }

  .cl-card__panel::before {
    top: -18%;
    inset-inline-end: -26%;
    width: 78%;
    padding-bottom: 78%;
  }

  .cl-card__panel::after {
    bottom: -30%;
    inset-inline-start: -20%;
    width: 56%;
    padding-bottom: 56%;
  }

  .cl-card[data-platform="ios"][data-tone="platform"] .cl-card__panel {
    background: linear-gradient(150deg, #FFF2F5 0%, #FFE5EC 52%, #FFDBE6 100%);
  }

  .cl-card[data-platform="ios"][data-tone="platform"] .cl-card__panel::before {
    background: radial-gradient(circle, rgba(255, 255, 255, .95), rgba(255, 255, 255, .35) 58%, rgba(255, 255, 255, 0) 74%);
  }

  .cl-card[data-platform="ios"][data-tone="platform"] .cl-card__panel::after {
    background: radial-gradient(circle, rgba(255, 59, 97, .3), rgba(255, 59, 97, .08) 58%, rgba(255, 59, 97, 0) 76%);
  }

  .cl-card[data-platform="android"][data-tone="platform"] .cl-card__panel {
    background: linear-gradient(150deg, #6247E8 0%, #7357F6 48%, #8C6DFF 100%);
  }

  .cl-card[data-platform="android"][data-tone="platform"] .cl-card__panel::before {
    background: radial-gradient(circle, rgba(206, 193, 255, .6), rgba(206, 193, 255, .16) 58%, rgba(206, 193, 255, 0) 76%);
  }

  .cl-card[data-platform="android"][data-tone="platform"] .cl-card__panel::after {
    background: radial-gradient(circle, rgba(255, 255, 255, .28), rgba(255, 255, 255, .06) 58%, rgba(255, 255, 255, 0) 76%);
  }

  /* Store-metadata releases — the two entries where nothing shipped to a
     device — keep the milky ground and a hairline arc instead of a wash. */
  .cl-card[data-tone="neutral"] .cl-card__panel::before {
    top: -14%;
    inset-inline-end: -22%;
    width: 70%;
    padding-bottom: 70%;
    border: 1px solid rgba(12, 11, 43, .07);
  }

  .cl-card[data-tone="neutral"] .cl-card__panel::after {
    bottom: -24%;
    inset-inline-start: -16%;
    width: 48%;
    padding-bottom: 48%;
    border: 1px solid rgba(12, 11, 43, .05);
  }

  .cl-card__bignum {
    position: absolute;
    inset-inline-end: 7%;
    bottom: 6%;
    max-width: 86%;
    color: rgba(12, 11, 43, .13);
    /* The fallback, for engines without container queries. */
    font-size: clamp(24px, 7.5vw, 32px);
    /* The panel is the container, so the numeral scales with the panel rather
       than with the viewport and "08.20" cannot outgrow the box the way a vw
       size did. */
    font-size: 31cqw;
    font-weight: 800;
    letter-spacing: -.06em;
    line-height: .82;
    font-variant-numeric: tabular-nums;
    /* The numeral is a graphic, not a data field — it must never be read out
       after the version that already sits in the copy column. */
    user-select: none;
  }

  .cl-card[data-platform="ios"][data-tone="platform"] .cl-card__bignum {
    color: rgba(255, 59, 97, .28);
  }

  .cl-card[data-platform="android"][data-tone="platform"] .cl-card__bignum {
    color: rgba(255, 255, 255, .34);
  }

  /* --- the improvements list --------------------------------------------- */

  .cl-card__items {
    margin: 0;
    padding: clamp(13px, 3.6vw, 16px) clamp(15px, 4.1vw, 18px) clamp(15px, 4.1vw, 18px);
    border-top: 1px solid var(--cl-line-2);
    list-style: none;
    display: grid;
    gap: clamp(7px, 2.1vw, 9px);
  }

  .cl-card__items > li {
    position: relative;
    padding-inline-start: 26px;
    color: var(--cl-ink-2);
    font-size: clamp(12px, 3.2vw, 13px);
    line-height: 1.4;
  }

  /* The marker is one inline SVG in its own span rather than a ::marker or a
     CSS-drawn glyph: ::marker can only animate colour, and the beam has to be
     able to swell the whole mark as it passes. */
  .cl-card__mark {
    position: absolute;
    top: .06em;
    inset-inline-start: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 17px;
    height: 17px;
    border-radius: 50%;
    background: var(--cl-accent-soft);
    color: var(--cl-accent);
  }

  .cl-card__mark svg { display: block; width: 10px; height: 10px; }

  /* --- show more --------------------------------------------------------- */

  /* The same height mechanism as css/creators-pages.css: grid-template-rows
     0fr -> 1fr on the wrapper with the clip supplying the overflow, so the
     cards keep their own sizes and gap and nothing is scaled into place.
     Collapsed it is visibility:hidden, which takes its content out of the tab
     order; the visibility transition is delayed by the length of the collapse
     so the cards stay on screen while the height runs out. */
  .cl-mobile__extra {
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    visibility: hidden;
    transition:
      grid-template-rows 260ms cubic-bezier(.4, 0, .2, 1),
      opacity 260ms cubic-bezier(.4, 0, .2, 1),
      visibility 0s linear 260ms;
  }

  .cl-mobile__extra-clip { min-height: 0; overflow: hidden; }

  /* The gap above the extra cards sits inside the clip, so it collapses too. */
  .cl-mobile__extra .cl-mobile__list { padding-top: clamp(16px, 4.4vw, 20px); }

  .cl-mobile__feed.is-expanded .cl-mobile__extra {
    grid-template-rows: 1fr;
    opacity: 1;
    visibility: visible;
    transition:
      grid-template-rows 260ms cubic-bezier(.4, 0, .2, 1),
      opacity 260ms cubic-bezier(.4, 0, .2, 1),
      visibility 0s;
  }

  .cl-mobile__toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    min-height: clamp(50px, 13.5vw, 56px);
    margin-top: clamp(18px, 5vw, 22px);
    padding: 0 20px;
    border: 1.5px solid var(--cl-ink);
    border-radius: 999px;
    background: #fff;
    color: var(--cl-ink);
    font-family: inherit;
    font-size: clamp(13px, 3.4vw, 14px);
    font-weight: 800;
    letter-spacing: -.005em;
    text-align: start;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
  }

  .cl-mobile__toggle:focus-visible {
    outline: 2px solid var(--cl-coral);
    outline-offset: 3px;
  }

  .cl-mobile__toggle[hidden] { display: none !important; }

  .cl-mobile__toggle-chevron {
    flex: 0 0 auto;
    width: 9px;
    height: 9px;
    margin: -4px 3px 0 12px;
    border-right: 1.6px solid currentColor;
    border-bottom: 1.6px solid currentColor;
    transform: rotate(45deg);
    transition: transform 260ms cubic-bezier(.4, 0, .2, 1);
  }

  .cl-mobile__feed.is-expanded .cl-mobile__toggle-chevron {
    margin-top: 4px;
    transform: rotate(225deg);
  }

  .cl-mobile__empty {
    margin: clamp(24px, 7vw, 32px) 0 0;
    color: var(--cl-ink-3);
    font-size: 14px;
  }

  .cl-mobile__empty[hidden] { display: none !important; }

  /* --- stagger reveal ---------------------------------------------------- */

  /* The hidden state sits behind cl-reveal, which only the script adds. With
     JS off, without IntersectionObserver, or with motion turned down the class
     never appears and the cards are simply there. */
  .cl-mobile__list.cl-reveal > .cl-card {
    opacity: 0;
    transform: translate3d(0, 12px, 0);
    will-change: opacity, transform;
  }

  .cl-mobile__list.cl-reveal > .cl-card.is-in {
    opacity: 1;
    transform: none;
    will-change: auto;
    transition:
      opacity 420ms cubic-bezier(.22, .61, .36, 1),
      transform 420ms cubic-bezier(.22, .61, .36, 1);
    transition-delay: var(--cl-seq, 0ms);
  }

  /* Cards inside the show-more clip opt out: that toggle already has a motion
     of its own, and two motions for one tap is one too many. */
  .cl-mobile__extra .cl-mobile__list.cl-reveal > .cl-card,
  .cl-mobile__extra .cl-mobile__list.cl-reveal > .cl-card.is-in {
    opacity: 1;
    transform: none;
    transition: none;
    will-change: auto;
  }

  /* Long feeds: skip layout for cards well below the fold. Kept off the first
     four on purpose — a skipped subtree has no layout, and the beam measures
     positions inside the first card. */
  .cl-mobile__list > .cl-card:nth-child(n + 5) {
    content-visibility: auto;
    contain-intrinsic-size: auto 420px;
  }

  /* --- the release beam -------------------------------------------------- */

  /* One injected element, a direct child of the card, clipped by the card's
     own overflow and radius. It is inset:0, so its own 100% *is* the card
     height: the travel needs no measurement and stays right even if a
     dictionary or font swap changes that height while it is in flight. */
  .cl-card__beam {
    position: absolute;
    inset: 0;
    z-index: 4;
    transform: translate3d(0, 0, 0);
    will-change: transform;
    pointer-events: none;
    animation: cl-beam-travel var(--cl-beam-ms, 800ms) linear var(--cl-beam-lead, 260ms) 1 both;
  }

  /* The line itself. bottom:100% parks it directly above the card, so the rail
     can start at translate 0 with nothing on screen. It overhangs 12% each
     side, so the gradient's transparent tips are clipped away and the visible
     line reaches both card edges at strength instead of stopping dead.
     No blend mode: this card is a coloured panel at the top and white at the
     bottom, and screen/plus-lighter would make the beam vanish over the white. */
  .cl-card__beam::before {
    content: "";
    position: absolute;
    inset-inline: -12%;
    bottom: 100%;
    height: var(--cl-beam-h, 92px);
    background:
      linear-gradient(90deg,
        rgba(255, 59, 97, 0) 0%, #FF3B61 18%, #A874F7 52%, #7357F6 82%,
        rgba(115, 87, 246, 0) 100%) 50% 50% / 100% 1.5px no-repeat,
      radial-gradient(120% 46px at 50% 50%,
        rgba(168, 116, 247, .2), rgba(255, 59, 97, .1) 46%, rgba(255, 59, 97, 0) 72%);
    opacity: 0;
    animation: cl-beam-life var(--cl-beam-ms, 800ms) linear var(--cl-beam-lead, 260ms) 1 both;
  }

  /* Position, and only position. Linear on purpose: it keeps the highlight
     delays below a closed form instead of something that has to be inverted
     numerically per element. */
  @keyframes cl-beam-travel {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(0, calc(100% + var(--cl-beam-h, 92px)), 0); }
  }

  /* It strikes in, holds, and is gone before the bottom edge, so the card is
     never left with a line sitting on its border. */
  @keyframes cl-beam-life {
    0%   { opacity: 0; transform: scaleX(.82); }
    12%  { opacity: 1; transform: scaleX(1); }
    82%  { opacity: 1; transform: scaleX(1); }
    100% { opacity: 0; transform: scaleX(.94); }
  }

  /* What the beam lights on its way. Both highlights are additions that return
     to their own resting values, so there is nothing for the reduced-motion
     block to undo and nothing left behind if one is cancelled halfway. */
  .cl-card--latest.is-beaming .cl-card__bignum {
    animation: cl-lit-num 420ms cubic-bezier(.22, .61, .36, 1)
      calc(var(--cl-beam-lead, 260ms) + var(--cl-lit-delay, 0ms)) 1;
  }

  @keyframes cl-lit-num {
    0%   { filter: none; }
    22%  { filter: brightness(1.5) saturate(1.3); }
    100% { filter: none; }
  }

  .cl-card--latest.is-beaming .cl-card__mark {
    animation: cl-lit-dot 320ms cubic-bezier(.22, .61, .36, 1)
      calc(var(--cl-beam-lead, 260ms) + var(--cl-lit-delay, 0ms)) 1;
  }

  @keyframes cl-lit-dot {
    0%   { transform: scale(1); }
    30%  { transform: scale(1.55); }
    100% { transform: scale(1); }
  }

  .cl-card__items > li::after {
    content: "";
    position: absolute;
    inset-inline: 26px 0;
    bottom: -3px;
    height: 1.5px;
    border-radius: 2px;
    background: linear-gradient(90deg, var(--cl-coral), var(--cl-violet));
    /* The resting state: not drawn at all. */
    opacity: 0;
    transform: scaleX(0);
    transform-origin: left center;
    pointer-events: none;
  }

  .cl-card--latest.is-beaming .cl-card__items > li::after {
    animation: cl-lit-rule 340ms cubic-bezier(.22, .61, .36, 1)
      calc(var(--cl-beam-lead, 260ms) + var(--cl-lit-delay, 0ms)) 1;
  }

  @keyframes cl-lit-rule {
    0%   { opacity: 0;   transform: scaleX(0); }
    35%  { opacity: .8; }
    60%  { opacity: .8;  transform: scaleX(1); }
    100% { opacity: 0;   transform: scaleX(1); }
  }

  /* --- narrow phones ----------------------------------------------------- */

  /* At 360 the panel would squeeze the title to three lines. Give the copy
     column more room and let the numeral come down a step. */
  @media (max-width: 374.98px) {
    .cl-card__main { grid-template-columns: minmax(0, 1fr) 35%; }
  }
}

/* Arabic is the only RTL locale here, and the site switches direction in CSS —
   there is no dir attribute anywhere. Mirrors the pattern at
   css/our-models.css:571. --cl-dir flips the segmented pill's travel, because
   transform stays physical while direction does not. */
@media (max-width: 991.98px) {
  html.lang-ar body.changelog-page .cl-mobile {
    direction: rtl;
    text-align: right;
    --cl-dir: -1;
  }

  html.lang-ar body.changelog-page .cl-card__items > li::after {
    transform-origin: right center;
  }
}

@media (max-width: 991.98px) and (prefers-reduced-motion: reduce) {
  /* The module already declines to add cl-reveal and never injects the beam
     under this preference. This block is what catches the preference being
     switched on after load — and it is deliberately the third guarantee about
     the beam, after "never built" and "removed when it ends". */
  .cl-mobile__list.cl-reveal > .cl-card,
  .cl-mobile__list.cl-reveal > .cl-card.is-in {
    opacity: 1;
    transform: none;
    transition: none;
    will-change: auto;
  }

  /* display:none, not opacity:0 — so it can never be parked mid-card as a
     stray line, and never holds a compositing layer. */
  .cl-card__beam { display: none; }

  /* The highlights only ever add to a finished resting state, so cancelling
     them is the whole fix: the numeral keeps its designed translucency and
     each bullet keeps its marker and its undrawn hairline. */
  .cl-card--latest.is-beaming .cl-card__bignum,
  .cl-card--latest.is-beaming .cl-card__mark,
  .cl-card--latest.is-beaming .cl-card__items > li::after { animation: none; }

  /* The pill still moves between segments — it arrives instead of travelling,
     which is the whole point of the control. */
  .cl-mobile__filter.is-ready .cl-mobile__filter__pill,
  .cl-mobile__filter__btn { transition: none; }

  /* The show more still opens and closes; it just arrives. */
  .cl-mobile__extra,
  .cl-mobile__feed.is-expanded .cl-mobile__extra { transition: visibility 0s; }

  .cl-mobile__toggle-chevron { transition: none; }
}
