/* ---------------------------------------------------------------------------
   eagle-one.css

   The page is built on apple.com/apple-intelligence's own stylesheet
   (apple/ai-overview.css) for the shared chrome. This file is the Eagle One
   layer, and every value in it was measured on their live page at a 1470px
   viewport or read out of their stylesheet/JS — sources noted inline.

   Rewritten as a single pass. The previous version had accumulated ~15 rounds
   of contradictory rules, which is why later overrides silently lost: the same
   selector appeared five times with different values. One definition each now.

   MEASURED SPEC (1470px viewport)
     content column      x105, width 1260   (padding 0 105px)
     lockup              840 wide, left aligned
     eyebrow             21px / 21px / 600
     headline            48px / 52.0077px / 600
     lockup copy         21px / 29.001px / 600
     caption heading     17px / 21.0012px / 600
     media caption       28px / 32px / 600, centred, max-width 584
     caption tile        372 wide (wide variant 696), card 450 tall
     caption padding     28px 15px 0
     tile gap            20px      lockup -> tiles 48px
     media card          1260 x 680, caption 48px below the card's top
     media rail          grid, 1260 columns, gap 20, padding 0 105px
     control             sticky, bottom 32px, 288 x 56, z-index 1
     platter / button    216 x 56 r28  /  56 x 56 r50%, rgb(232 232 237)
     dots                8px, current 48px, rgba(29,29,31,.35)
     paddle              36 x 36 r36, rgba(210,210,215,.64) on rgba(0,0,0,.56),
                         transition 100ms linear
     welcome lockup      462 tall, align-items:center
     welcome stills      260x288 (inner), 182x220 (outer)
     welcome device      226 x 462
     fan                 translateX 200/340 -> 70/90 over 4s
                         cubic-bezier(0.165, 0.84, 0.44, 1)
     slide               1000ms easeInOutCubic (easeOutCubic on touch)
--------------------------------------------------------------------------- */

/* --- real screenshots ------------------------------------------------------ */
/* Where there is actual app art, it replaces the gradient rather than sitting on
   top of one. These are UI shots on a near-white ground, so they carry their own
   background and want `cover`: the card floats centrally in each source frame,
   so cropping to the tile's 372x450 takes only empty margin off the top and
   bottom and never touches the card. */
.eo-shot { position: absolute; inset: 0; overflow: hidden; background: #f5f5f7; }
.eo-shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* The phone is the exception: a full screen must not be cropped, and the bezel
   aperture is already the right shape for it. */
.section-welcome .device-main-screen.eo-shot img { object-fit: cover; object-position: top center; }

/* --- gradient placeholders ------------------------------------------------- */
.eo-art {
  position: relative;
  background-color: var(--eo-base);
  background-image:
    radial-gradient(115% 85% at 80% 8%,  var(--eo-hi) 0%, transparent 58%),
    radial-gradient(95% 72% at 12% 94%,  var(--eo-lo) 0%, transparent 62%);
  overflow: hidden;
}
.eo-g1 { --eo-base:#C7343F; --eo-hi:#FF7A4E; --eo-lo:#7E2E86; }
.eo-g2 { --eo-base:#2C6E63; --eo-hi:#6FD8B0; --eo-lo:#123C46; }
.eo-g3 { --eo-base:#3C5BC4; --eo-hi:#7FD1FF; --eo-lo:#1B2A7A; }
.eo-g4 { --eo-base:#B03A6E; --eo-hi:#F0674B; --eo-lo:#3E2160; }
.eo-g5 { --eo-base:#C4762F; --eo-hi:#FFC46B; --eo-lo:#8E3A2B; }
.eo-g6 { --eo-base:#7A3D8E; --eo-hi:#C083E0; --eo-lo:#2A1750; }

/* --- welcome --------------------------------------------------------------- */
.section-welcome {
  --image-translate-start: 200px;
  --image-translate-start-secondary: 340px;
  --image-translate-end: 70px;
  --image-translate-end-secondary: 90px;
  --hero-easing: cubic-bezier(0.165, 0.84, 0.44, 1);
}
.section-welcome .welcome-media-lockup {
  display: flex;
  align-items: center;        /* their value: this alone yields y87 / y121 */
  justify-content: center;
  height: 462px;
  position: relative;
}
.section-welcome .welcome-image { position: relative; flex: none; border-radius: 24px; overflow: hidden; }
.section-welcome .welcome-image.image-left,
.section-welcome .welcome-image.image-right { width: 260px; height: 288px; z-index: 1; }
.section-welcome .welcome-image.image-left-secondary,
.section-welcome .welcome-image.image-right-secondary { width: 182px; height: 220px; z-index: 0; }

.section-welcome .device-main { position: relative; z-index: 2; flex: none; width: 226px; height: 462px; }
.section-welcome .device-main-hardware.device { --device-w: 226px; width: 226px; margin: 0; }
/* Their screen is masked to the shape of a video they serve from apple.com.
   A cross-origin mask is a CORS fetch, apple.com sends no ACAO header, and a
   mask that fails to load takes the element with it — that was the blank white
   phone. It is the only remote mask in their whole stylesheet. */
.section.section-welcome .device-main .device-main-screen {
  -webkit-mask-image: none; mask-image: none;
}
/* Matched to their selector depth on purpose: theirs is
   `.section.section-welcome .device-main .device-main-screen` at (0,4,0), which
   out-scores a three-class selector and puts the screen back into flow — that
   is what made it overflow the bezel aperture. */
.section.section-welcome .device-main .device-main-screen.device-screen {
  position: absolute;
  left: 5.3333%; top: 2.5%; width: 89.3333%; height: 95%;
  border-radius: calc(226px * 0.126);
  overflow: hidden;
}

/* the fan-out: their tokens, released by .eo-fanned (their marquee class) */
.js .section-welcome .welcome-media-lockup { opacity: 0; }
.js .section-welcome.eo-ready .welcome-media-lockup { opacity: 1; transition: opacity .2s; }
.js .section-welcome .welcome-image { transition: transform 4s var(--hero-easing); transition-delay: .2s; }
.js .section-welcome .image-left            { transform: translateX(var(--image-translate-start)); }
.js .section-welcome .image-left-secondary  { transform: translateX(var(--image-translate-start-secondary)); }
.js .section-welcome .image-right           { transform: translateX(calc(var(--image-translate-start) * -1)); }
.js .section-welcome .image-right-secondary { transform: translateX(calc(var(--image-translate-start-secondary) * -1)); }
.js .section-welcome.eo-fanned .image-left            { transform: translateX(var(--image-translate-end)); }
.js .section-welcome.eo-fanned .image-left-secondary  { transform: translateX(var(--image-translate-end-secondary)); }
.js .section-welcome.eo-fanned .image-right           { transform: translateX(calc(var(--image-translate-end) * -1)); }
.js .section-welcome.eo-fanned .image-right-secondary { transform: translateX(calc(var(--image-translate-end-secondary) * -1)); }
.js .section-welcome .device-main { transform: scale(1.06); transition: transform 3s var(--hero-easing); }
.js .section-welcome.eo-fanned .device-main { transform: scale(1); }

/* --- section lockups ------------------------------------------------------- */
.ric-type-lockup { max-width: 840px; text-align: start; }
.ric-type-lockup-eyebrow  { font-size: 21px; line-height: 1; font-weight: 600; margin: 0; }
.ric-type-lockup-headline { font-size: 48px; line-height: 1.0835; font-weight: 600; letter-spacing: -.003em; margin: 12px 0 0; }
.ric-type-lockup-copy     { font-size: 21px; line-height: 1.381; font-weight: 600; margin: 24px 0 0; }

/* --- caption-tile galleries ------------------------------------------------ */
.caption-tile-gallery .scroll-container {
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none;
  padding: 10px 0 30px; margin: -10px 0 -30px;
}
.caption-tile-gallery .scroll-container::-webkit-scrollbar { display: none; }
.caption-tile-gallery .item-container { width: max-content; padding: 0 105px; margin: 48px 0 0; }
.caption-tile-set { display: flex; gap: 20px; margin: 0; padding: 0; list-style: none; width: max-content; }
.caption-tile-set > .caption-tile { flex: 0 0 372px; width: 372px; display: flex; flex-direction: column; }
.caption-tile-set > .caption-tile.wide { flex: 0 0 696px; width: 696px; }
.caption-tile .card.tile.tile-rounded {
  order: 1; width: 100%; height: 450px;
  border-radius: 28px; overflow: hidden; position: relative;
}
.caption-tile .card-caption-content {
  order: 2; width: auto; padding: 28px 15px 0;
  font-size: 17px; line-height: 1.2353; font-weight: 600; letter-spacing: -.022em; text-align: start;
}
.caption-tile .card-caption-heading { display: block; font-weight: 600; margin: 0; }
.caption-tile .caption-eyebrow { display: block; font-weight: 400; opacity: .64; margin: 0 0 2px; }
.caption-tile .caption-copy    { display: block; font-weight: 400; opacity: .64; margin: 2px 0 0; }
.caption-tile .media-block { display: contents; }
.caption-tile .positioned-media-element { position: absolute; inset: 0; width: auto; height: auto; }

/* --- highlights: media-card gallery ---------------------------------------- */
/* Their gallery does NOT scroll: animateToItem() sets the scroller's scrollLeft
   to 0 and translates .item-container. Holding overflow hidden here keeps the
   two from fighting.

   The card metrics are their formulas rather than my arithmetic, so they hold
   at every width instead of only at the three I measured:

     --shared-media-gallery-width   min(viewport-content, content-max-width)
     --shared-media-gallery-padding max(6.25vw, (100vw - max-width) / 2)
     --shared-media-gallery-height  680 / 628 / 480

   and the artwork is full-bleed at exactly the card size — their own
   --p-width/--p-height pairs are 1260x680, 934x628 and 420x480. */
.media-card-set {
  --gallery-max-width: 1260px;          /* --global-content-max-width */
  --gallery-min-width: 280px;
  --gallery-width: min(max(87.5vw, var(--gallery-min-width)), var(--gallery-max-width));
  --gallery-padding: max(6.25vw, calc((100vw - var(--gallery-max-width)) / 2));
  --gallery-height: 680px;
}
/* Their sheet already carries the right padding, but only via
   `.section:has(.all-access-pass) { padding-bottom: var(--global-section-aap-padding) }`.
   Without that class on our control, the competing rule that collapses two
   adjacent background-alt sections won instead and the section lost all 216px
   of its bottom padding — which in turn cut the control's active band in half.
   The control carries `all-access-pass` now, so every structural :has() rule of
   theirs resolves exactly as it does on their page. */
.section-highlights .media-gallery.scroll-container {
  position: relative; overflow: hidden;
  box-sizing: content-box;
  height: var(--gallery-height);
  width: 100%; margin: 0 auto -30px;
  padding-bottom: 30px;                          /* --staggered-translate-y */
}
.section-highlights .media-gallery .item-container { will-change: transform; }
.media-gallery .card-set {
  display: grid; grid-auto-flow: column;
  grid-auto-columns: var(--gallery-width);
  gap: 20px; padding: 0 var(--gallery-padding);
  margin: 0 auto; list-style: none; width: max-content;
}
.media-gallery .card-set > .gallery-item {
  display: flex; width: var(--gallery-width); height: var(--gallery-height);
  list-style: none;
}
.media-gallery .card.tile.tile-rounded {
  width: 100%; height: 100%; border-radius: 28px;
  overflow: hidden; position: relative; background: #000;
}
.media-gallery .caption-container { position: absolute; inset: 0; padding: 0; text-align: center; z-index: 2; }
.media-gallery .caption-container.pin-bottom-center { align-content: end; }
.media-gallery .caption-container.large-pin-center-left { align-content: center; text-align: start; }
.media-gallery .caption-animation-container { padding: 0 40px; margin-top: 48px; }
.media-gallery .caption-container.pin-bottom-center .caption-animation-container { margin: 0 0 48px; }
.media-gallery .caption {
  margin: 0 auto; max-width: 584px;
  font-size: 28px; line-height: 1.1428; font-weight: 600; letter-spacing: .007em;
}
.media-gallery .caption-container.large-pin-center-left .caption { margin-inline: 0; }
.media-gallery .caption .caption-copy {
  display: block; margin-top: 10px; max-width: none;
  font-size: 17px; line-height: 1.2353; font-weight: 400; letter-spacing: -.022em; opacity: .86;
}
.media-gallery .media-block { display: contents; }
.media-gallery .positioned-media-element {
  /* .media-block .positioned-media-element { width: var(--p-width, 100%);
     height: var(--p-height, 100%) } and every --p-width/--p-height pair on this
     section equals the card. The artwork IS the card, full bleed. The inset
     rectangle an earlier pass used was the black-margin bug. */
  position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 0;
}
.media-gallery .card.tile.tile-rounded::after {
  /* a top-and-bottom scrim so the caption holds up over the art */
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(rgba(0,0,0,.30) 0%, rgba(0,0,0,0) 32%, rgba(0,0,0,0) 68%, rgba(0,0,0,.30) 100%);
}

/* --- the gallery control --------------------------------------------------- */
/* Their structure, read out of ai-overview.css rather than guessed:
     .all-access-pass__container  absolute, height 75%, bottom 0, flex-end,
                                  overflow clip, pointer-events none, z 9995
     .all-access-pass             position sticky, bottom var(--aap-margin)=32px,
                                  margin 32px 0 100px, pointer-events auto
     tokens                       --aap-min-height 56, --aap-bubble-gap 16,
                                  --sk-dotnav-size 8, --sk-dotnav-margin-inline 8,
                                  --progress-bar-active-width 48,
                                  --aap-background-color-solid 232 232 237,
                                  --aap-background-color-alpha .28, --aap-blur 7px,
                                  --autoplay-persist-duration 6.15s
   The platter's 216px is derived, not chosen: 5 dots x (8 + 16 margin) = 120,
   plus the 48px current dot + its 16px margin = 64, plus 16px dotnav padding
   either side = 216. 216 + 16 gap + 56 button = the 288 measured. */
.all-access-pass__container {
  /* their :has() override is top:auto;bottom:0 — without the top:auto the base
     rule's top:0 wins against bottom and the control clamps to the TOP of the
     gallery, which is what used to leave it sitting inside the card. */
  position: absolute; left: 0; top: auto; bottom: 0; width: 100%; height: 75%;
  display: flex; align-items: flex-end; justify-content: center;
  margin: 0; overflow: clip; pointer-events: none; z-index: 9995;
}
.eo-gallery-control {
  --aap-min-height: 56px;
  --aap-bubble-gap: 16px;
  --aap-margin: 32px;
  --dot-size: 8px;
  --dot-margin: 8px;
  --dot-active-width: 48px;
  --aap-background: rgb(232 232 237 / .72);   /* 1 - 1 x .28 */
  --aap-blur: 7px;
  --aap-dotnav-background: rgba(29, 29, 31, .6);
  --aap-dotnav-background-hover: rgba(0, 0, 0, .54);
  --aap-active-fill-color: #29292a;
  --aap-icon-color: rgb(29, 29, 31);
  --aap-button-hover: rgba(223, 223, 227, .698);
  --aap-button-active: rgba(193, 193, 198, .654);
  --autoplay-duration: 6.15s;
  position: sticky;
  bottom: var(--aap-margin);
  margin: var(--aap-margin) 0 100px;
  display: flex; align-items: center;
  pointer-events: auto;
  will-change: transform;
  z-index: 1;
}
.theme-dark .eo-gallery-control {
  --aap-background: rgb(42 42 45 / .72);
  --aap-dotnav-background: rgba(245, 245, 247, .8);
  --aap-dotnav-background-hover: rgba(255, 255, 255, .48);
  --aap-active-fill-color: rgb(245, 245, 247);
  --aap-icon-color: rgb(245, 245, 247);
  --aap-button-hover: rgba(73, 73, 76, .726);
  --aap-button-active: rgba(57, 57, 60, .742);
}

/* Both bubbles are the same component: a rounded box with an expanding
   backdrop-blurred platter behind it. Theirs fades in on .activated. */
.eo-aap-element {
  position: relative; box-sizing: border-box;
  display: flex; align-items: center; justify-content: space-between;
  min-height: var(--aap-min-height);
  border-radius: 28px;
  opacity: 0;
  transition: opacity 200ms ease-in;
}
.eo-aap-element::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  border-radius: 28px;
  background-color: var(--aap-background);
  backdrop-filter: blur(var(--aap-blur));
  -webkit-backdrop-filter: blur(var(--aap-blur));
  transform: scaleX(calc(var(--aap-min-height) / 100%));
  transform-origin: center;
  opacity: 0;
}
.eo-gallery-control.activated .eo-aap-element { opacity: 1; }
.eo-gallery-control.activated .eo-aap-element::before {
  opacity: 1; transform: none;
  transition: transform 500ms cubic-bezier(0.28, 0.11, 0.32, 1), opacity 250ms linear;
}

/* dot platter */
.eo-dots-platter { padding: 0 16px; }
.eo-dots {
  display: inline-flex; align-items: center; justify-content: center;
  line-height: 0; margin: 0; padding: 0; list-style: none;
}
.eo-dot {
  position: relative; list-style: none;
  margin-block: 0; margin-inline: var(--dot-margin);
  width: auto;
}
.eo-dot-hit {
  display: flex; align-items: center; justify-content: center;
  width: var(--dot-size); height: var(--dot-size);
  padding: 0; border: 0; border-radius: 10px;
  background-color: var(--aap-dotnav-background);
  cursor: pointer; position: relative;
  transition: width 250ms cubic-bezier(0.28, 0.11, 0.32, 1),
              background-color 250ms linear;
}
/* their hit area: an invisible 8px skirt on every side */
.eo-dot-hit::before { content: ""; position: absolute; padding: var(--dot-size); width: 100%; height: 100%; }
.eo-dot-hit:hover { background-color: var(--aap-dotnav-background-hover); }
.eo-dot.is-current .eo-dot-hit {
  width: var(--dot-active-width);
  overflow: hidden; cursor: default;
  background-color: var(--aap-dotnav-background);
}
.eo-dot.is-current .eo-dot-hit:hover { background-color: var(--aap-dotnav-background); }
/* the fill sweep. Theirs is an ::after that grows from a 15% stub, paused
   unless the control is .playing — same animation, same 6.15s, same linear. */
.eo-dot.is-current .eo-dot-hit::after {
  content: ""; position: absolute; top: 0; inset-inline-start: 0;
  width: 0; min-width: 15%; height: 100%;
  margin-inline-start: -15%;
  border-radius: 10px;
  background-color: var(--aap-active-fill-color);
  animation: eo-aap-progress var(--autoplay-duration) linear paused forwards;
}
.eo-gallery-control.playing .eo-dot.is-current .eo-dot-hit::after { animation-play-state: running; }
@keyframes eo-aap-progress { to { width: 100%; } }

/* play / pause bubble */
.eo-playpause-wrapper {
  order: 2;
  height: var(--aap-min-height); width: var(--aap-min-height);
  margin-inline-start: var(--aap-bubble-gap);
  border-radius: 50%;
}
.eo-playpause-wrapper::before { border-radius: 50%; }
.eo-playpause {
  height: 100%; width: 100%; padding: 0; border: 0;
  background: none; border-radius: 32px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  position: relative;
  transition: background-color 100ms linear;
}
.eo-playpause:hover  { background-color: var(--aap-button-hover); }
.eo-playpause:active { background-color: var(--aap-button-active); }
.eo-playpause .svg-icon {
  height: 100%; width: 100%; display: none;
  fill: var(--aap-icon-color);
  transition: fill 250ms linear;
}
.eo-gallery-control.playing .eo-playpause .pause-icon,
.eo-gallery-control.paused  .eo-playpause .play-icon,
.eo-gallery-control.ended   .eo-playpause .replay-icon { display: block; }

/* --- paddles --------------------------------------------------------------- */
.paddlenav .paddlenav-arrow {
  width: 36px; height: 36px; border-radius: 36px; padding: 0; border: 0;
  background: rgba(210, 210, 215, .64); color: rgba(0, 0, 0, .56); fill: currentColor;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  transition: background 100ms linear, color 100ms linear, opacity 100ms linear;
}
.paddlenav .paddlenav-arrow:hover { color: rgba(0, 0, 0, .64); }
.paddlenav .paddlenav-arrow:disabled { opacity: .42; pointer-events: none; }
.paddlenav .paddlenav-arrow svg { width: 36px; height: 36px; display: block; fill: currentColor; }
.paddlenav .paddlenav-arrow-previous svg { transform: scaleX(-1); }
.scroll-gallery-paddlenav {
  display: flex; justify-content: flex-end;
  box-sizing: border-box; width: 100%; max-width: 100%;
  padding: 20px 105px 0;
}
.scroll-gallery-paddlenav ul { display: flex; gap: 12px; list-style: none; margin: 0; padding: 0; }
.scroll-gallery-paddlenav.hide { display: none; }

/* --- callouts, cards ------------------------------------------------------- */
/* Their tile carries --sk-tile-padding-large: 60px 8.3333333333%, and
   .section-card .tile-content adds padding-block 120/80/60 with the headline
   40px under the icon. Without the 8.33% inline padding our card copy ran the
   full 1260 and read as a wall. */
.section-card .card.tile { padding-inline: 8.3333333333%; }
.section-card .tile-content {
  display: flex; flex-direction: column; align-items: center;
  text-align: center; padding-block: 120px;
}
.section-card .tile-content .section-card-headline { margin-top: 40px; }
.section-card .tile-content .section-card-copy { color: #6e6e73; margin-top: 16px; }
.section-card .tile-content .section-card-icon {
  display: block; width: 68px; height: 68px; border-radius: 15px;
}
.section-privacy .list-container { font-weight: 600; margin-top: 24px; }
.section-privacy .list-container ul { display: flex; list-style: none; margin: 0; padding: 0; }
.section-privacy .list-container ul li {
  margin-inline: 16px; margin-block-start: 12px;
  padding-inline-start: 32px; text-align: start;
  background-repeat: no-repeat; background-position: left 3px; background-size: 19px 19px;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 19 19'%3E%3Cpath fill='none' stroke='%236e6e73' stroke-width='1.2' d='M9.5 1a8.5 8.5 0 1 1 0 17 8.5 8.5 0 0 1 0-17z'/%3E%3Cpath fill='none' stroke='%236e6e73' stroke-width='1.4' d='m5.8 9.6 2.6 2.6 4.8-5.2'/%3E%3C/svg%3E");
}
/* Their callouts are a subgrid: icon row, then copy row, so the copy baselines
   line up across the row regardless of icon height. `.callouts .callout
   .callout-icon-wrapper { margin-bottom: 8px }` is theirs; the icon itself is
   an app icon, which for us is the gradient at app-icon size. */
.callouts .callout .callout-icon-wrapper { margin-bottom: 8px; }
.callouts .callout .callout-icon {
  display: block; width: 64px; height: 64px; border-radius: 14px;
}

/* --- staggered reveal ------------------------------------------------------ */
.js [data-staggered-item] { opacity: 0; transform: translateY(24px); }
.js [data-staggered-item].eo-in {
  opacity: 1; transform: none;
  transition: opacity .6s cubic-bezier(0.28,0.11,0.32,1) var(--eo-delay,0s),
              transform .6s cubic-bezier(0.28,0.11,0.32,1) var(--eo-delay,0s);
}

/* --- breakpoints ----------------------------------------------------------- */

@media only screen and (max-width: 1068px) {
  .caption-tile-gallery .item-container { padding: 0 38px; }
  .media-card-set { --gallery-height: 628px; }
  .scroll-gallery-paddlenav { padding: 20px 38px 0; }
  .section-welcome .welcome-media-lockup { height: 392px; }
  .section-welcome .welcome-image.image-left,
  .section-welcome .welcome-image.image-right { width: 208px; height: 230px; }
  .section-welcome .welcome-image.image-left-secondary,
  .section-welcome .welcome-image.image-right-secondary { width: 146px; height: 176px; }
  .section-welcome .device-main { width: 192px; height: 392px; }
  .section-welcome .device-main-hardware.device { --device-w: 192px; width: 192px; }
  .section-welcome { --image-translate-start: 150px; --image-translate-start-secondary: 250px; }
  .ric-type-lockup-headline { font-size: 40px; }
}
@media only screen and (max-width: 734px) {
  .caption-tile-gallery .item-container { padding: 0 22px; }
  .caption-tile-set > .caption-tile,
  .caption-tile-set > .caption-tile.wide { flex-basis: 280px; width: 280px; }
  .caption-tile .card.tile.tile-rounded { height: 340px; }
  .media-card-set { --gallery-max-width: 420px; --gallery-height: 480px; }
  /* 21px in a 257px column is about twenty characters a line, which is a third
     of a readable measure and reads as a column of broken phrases. Narrower
     padding and a step down in size buy back most of it. */
  .media-gallery .caption-animation-container { padding: 0 16px; margin-top: 32px; }
  .media-gallery .caption { font-size: 19px; max-width: none; }
  .scroll-gallery-paddlenav { padding: 20px 22px 0; }
  .section-welcome .welcome-media-lockup { height: 300px; }
  .section-welcome .welcome-image.image-left-secondary,
  .section-welcome .welcome-image.image-right-secondary { display: none; }
  .section-welcome .welcome-image.image-left,
  .section-welcome .welcome-image.image-right { width: 150px; height: 200px; }
  /* The hero is a phone, on a phone. At 148px it was 34% of a 390px viewport,
     floating in white with its own screenshot too small to read; the page opened
     on a picture of the product that did not show the product. At 206px it is
     just over half the width, the app's own UI is legible inside it, and the two
     cards behind still peek out at the sides. */
  .section-welcome .welcome-media-lockup { height: 420px; }
  .section-welcome .device-main { width: 206px; height: 418px; }
  .section-welcome .device-main-hardware.device { --device-w: 206px; width: 206px; }
  .ric-type-lockup-headline { font-size: 32px; }
  .ric-type-lockup-copy { font-size: 19px; }
}
/* Below about 375px the hero lockup has to come down again: 206px of phone in a
   320px viewport leaves no room for the cards behind it, and they are what make
   the lockup read as a composition rather than a screenshot. */
@media only screen and (max-width: 374px) {
  .section-welcome .welcome-media-lockup { height: 372px; }
  .section-welcome .device-main { width: 176px; height: 357px; }
  .section-welcome .device-main-hardware.device { --device-w: 176px; width: 176px; }
  .section-welcome .welcome-image.image-left,
  .section-welcome .welcome-image.image-right { width: 124px; height: 168px; }
}

@media (prefers-reduced-motion: reduce) {
  .js .section-welcome .welcome-media-lockup { opacity: 1; }
  .js .section-welcome .welcome-image,
  .js .section-welcome .device-main { transition: none; }
  .js .section-welcome .image-left            { transform: translateX(var(--image-translate-end)); }
  .js .section-welcome .image-left-secondary  { transform: translateX(var(--image-translate-end-secondary)); }
  .js .section-welcome .image-right           { transform: translateX(calc(var(--image-translate-end) * -1)); }
  .js .section-welcome .image-right-secondary { transform: translateX(calc(var(--image-translate-end-secondary) * -1)); }
  .js .section-welcome .device-main { transform: none; }
  .js [data-staggered-item] { opacity: 1; transform: none; }
  .eo-dot.is-current .eo-dot-hit::after { animation: none; transform: scaleX(1); }
  .eo-dot { transition: none; }
}

.section-welcome .welcome-image img { display:block; width:100%; height:100%; object-fit:cover; }

/* A white glyph centred on a gradient placeholder. Used where the honest art is
   a symbol rather than a screenshot: the "Not an emergency service" tile, the
   four callouts and the privacy card. */
.eo-glyph { display: flex; align-items: center; justify-content: center; color: #fff; }
.eo-glyph .glyph { width: 52%; height: 52%; }
.positioned-media-element.eo-glyph .glyph { width: 112px; height: 112px; }
.callouts .callout .callout-icon.eo-glyph,
.section-card .tile-content .section-card-icon.eo-glyph { display: flex; }
.section-card .tile-content .section-card-icon.eo-glyph { margin-inline: auto; }
.caption-tile .media-block .positioned-media-element.eo-glyph > svg.glyph {
  width: 112px; height: 112px; flex: none;
}

/* Apple's .icon.more draws its chevron as a glyph in SF Pro Icons, through
   both pseudo-elements. That font isn't loaded here, so each one rendered as a
   tofu box beside the inline SVG chevron the markup already carries. */
.section-compatibility .devices .icon.more::before,
.section-compatibility .devices .icon.more::after { content: none; }
