/* ==========================================================================
   Oplo Developer — dev.oplocloud.com.

   The developer's door into Oplo. One bar, its own — the mark with
   "Developer" beside it, its own links, menus and search — and under it
   oplocloud.com's own footer, which is the way back to the company. Both are
   generated into index.html and oplo-chrome.css by tools/build.py, from the
   same nav() and FOOTER every page on the site is built from, so the bar here
   and the bar there cannot drift apart.

   Between them it takes its manners from Apple's developer site: black the
   whole way down, a peek carousel at the top, rails you swipe, and panels of
   quiet grey on the black.

   Dark, and not as a theme. A developer site is read at night and read for a
   long time, and the black is what makes the one band of colour at the bottom
   land. Everything else on it is black, white and grey, which is the house
   rule: colour is spent once.

   Every class here is `dv-` prefixed, so nothing here can reach the chrome's
   styles and nothing there can reach these.
   ========================================================================== */

.dv {
  --dv-ink:   #f5f5f7;
  --dv-ink-2: #a1a1a6;
  --dv-ink-3: #6e6e73;
  --dv-bg:    #000;
  --dv-panel: #1d1d1f;
  --dv-panel-2: #161617;
  --dv-rule:  rgba(255, 255, 255, .12);
  --dv-blue:  #2997ff;
  --dv-blue-solid: #0071e3;
  --dv-wrap:  1024px;
  --dv-display: "SF Pro Display", -apple-system, BlinkMacSystemFont, "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --dv-text: "SF Pro Text", -apple-system, BlinkMacSystemFont, "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --dv-ease: cubic-bezier(.2, .8, .2, 1);

  background: var(--dv-bg); color: var(--dv-ink);
  font-family: var(--dv-text); font-size: 17px; line-height: 1.47; letter-spacing: -.022em;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  -webkit-tap-highlight-color: transparent;
}
/* The page is black, so the scrollbar and every form control the browser
   draws should be too. */
html { color-scheme: dark; }
html, body { margin: 0; background: #000; }
body.dv-locked { overflow: hidden; }
.dv *, .dv *::before, .dv *::after { box-sizing: border-box; }
.dv h1, .dv h2, .dv h3, .dv p, .dv ul { margin: 0; }
/* The footer's notes number themselves with a counter, so the browser's own
   marker would print every number twice. */
.dv ul, .dv ol { list-style: none; }
.dv ul { padding: 0; }
/* At no specificity, so every button and link below still decides its own
   colour. A plain `.dv a { color: inherit }` outranks `.dv-pill`, and paints
   white text onto the white pill. */
:where(.dv) a { color: inherit; text-decoration: none; }
:where(.dv) button { font: inherit; letter-spacing: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
.dv svg { display: block; }
.dv :focus-visible { outline: 2px solid var(--dv-blue); outline-offset: 3px; border-radius: 6px; }
.dv-wrap { width: min(var(--dv-wrap), calc(100% - 44px)); margin: 0 auto; }

/* A link from the bar — or from its menus, which point at single cards —
   scrolls what it names clear of the bar rather than underneath it. */
.dv [id] { scroll-margin-top: 66px; }

/* ----------------------------------------------------------------- The bar
   One bar, and it is this site's own: the mark with "Developer" beside it,
   its own links and menus, its own search, and a Sign in at the end. Not
   oplocloud.com's bar with a sub-bar under it — somebody who typed
   dev.oplocloud.com came for the platform, and the first thing they meet
   should be the platform's front door. The way back to the company is the
   footer, which is the company's footer entire.

   It is the site's `.nav` markup and the site's `.nav` rules, built by the
   same nav() in tools/build.py, so oplo-menu.js and oplo-search.js drive it
   without knowing which of the two they are looking at.

   Taller than the site's 44px, because the wordmark needs the room —
   developer.apple.com's bar is 52px for the same reason. The token is set on
   the bar, on what it opens, and on the page, so the three agree. It is
   written after oplo-chrome.css in index.html, which is what lets a selector
   of the same weight win. */
.dv, .dv .nav, .dv .nav-flyout, .dv .nav-find { --nav: 52px; }
.dv .nav { position: fixed; }
/* Room for it. The main site puts this on the body; here the page owns its
   own layout, so the page carries it. */
.dv-main { padding-top: var(--nav); }
/* The page is black the whole way down, so the bar and everything it opens —
   the menus, the search sheet — are dark material, the same tokens the site
   turns over on a dark page. */
.dv .nav {
  --paper: #161617;
  --ink: #f5f5f7;
  --ink-2: #a1a1a6;
  --ink-3: #a1a1a6;
  --rule: rgba(255, 255, 255, .16);
  --blue: #2997ff;
}
.dv .nav::before { background-color: rgba(22, 22, 23, .72); }

/* The lockup: the mark, then the name of which Oplo site this is. One link,
   so the whole thing is the way home. */
.dv .nav-brand { gap: 8px; opacity: 1; }
.dv .nav-brand .mark { height: 20px; }
.dv .nav-word {
  font-family: var(--dv-display);
  font-size: 21px; font-weight: 600; letter-spacing: .011em; line-height: 1;
  color: var(--dv-ink); white-space: nowrap;
}
.dv .nav-brand:hover .nav-word { opacity: .85; }
/* The links sit next to the wordmark rather than spread across the bar, the
   way a product's own nav does — space-evenly is for five doors into a
   company, not six sections of one site. */
.dv .nav-links { flex: 0 1 auto; justify-content: flex-start; gap: 26px; padding: 0 30px; }
.dv .nav-end { margin-left: auto; align-items: center; gap: 16px; }
.dv .nav-cta {
  flex: none; padding: 7px 14px; border-radius: 100px;
  background: var(--dv-blue-solid); color: #fff;
  font-size: 12px; line-height: 1; white-space: nowrap;
  transition: background .2s var(--dv-ease);
}
.dv .nav-cta:hover { background: #0077ed; }

/* ------------------------------------------------------------- Media slot
   The same contract as OEdu's welcome page: a div that names itself and the
   size it wants, and draws that label until a file is written into data-src.
   dev.js fills it. */
.dv-media { position: relative; overflow: hidden; background: #1d1d1f; }
.dv-media > img, .dv-media > video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.dv-media.dv-bare { background: transparent; }
.dv-media.dv-bare > img, .dv-media.dv-bare > video { object-fit: contain; }
.dv-media.is-empty { display: grid; place-items: center; background: linear-gradient(150deg, #232325, #131315); }
.dv-media.is-empty::after {
  content: ""; position: absolute; inset: 10px; border-radius: inherit; pointer-events: none;
  border: 1.5px dashed rgba(255, 255, 255, .14);
}
.dv-media.dv-dark.is-empty { background: radial-gradient(120% 90% at 50% 20%, #2e2e33, #0c0c0e); }
.dv-media.dv-bare.is-empty { background: linear-gradient(150deg, #212123, #151517); }
.dv-slot { position: relative; z-index: 1; display: grid; justify-items: center; gap: 5px; padding: 18px; text-align: center; color: rgba(255, 255, 255, .5); }
.dv-slot svg { width: 30px; height: 30px; margin-bottom: 2px; opacity: .75; }
.dv-slot b { font-size: 13px; font-weight: 600; letter-spacing: -.01em; }
.dv-slot small { font-size: 11.5px; letter-spacing: 0; }

/* -------------------------------------------------------------- Type ladder */
.dv-h2 {
  font-family: var(--dv-display);
  font-size: clamp(28px, 3.4vw, 40px); line-height: 1.1; font-weight: 600; letter-spacing: -.003em;
}
.dv-lead { max-width: 46ch; margin-top: 14px; color: var(--dv-ink-2); font-size: 17px; line-height: 1.5; }
.dv-fine { margin-top: 26px; color: var(--dv-ink-3); font-size: 13px; line-height: 1.5; max-width: 62ch; }
.dv-link { display: inline-block; color: var(--dv-blue); font-size: 15px; }
.dv-link:hover { text-decoration: underline; }
.dv-btn {
  display: inline-block; margin-top: 22px; margin-right: 18px;
  padding: 11px 21px; border-radius: 100px;
  background: var(--dv-blue-solid); color: #fff; font-size: 15px; line-height: 1;
  transition: background .2s var(--dv-ease);
}
.dv-btn:hover { background: #0077ed; }
.dv-btn.is-light { background: #fff; color: #1d1d1f; }
.dv-btn.is-light:hover { background: rgba(255, 255, 255, .88); }
.dv-btn + .dv-link { margin-top: 22px; }

/* ------------------------------------------------------------------- Bands */
.dv-band { padding: clamp(56px, 8vw, 96px) 0; }
.dv-band.dv-soft { background: #0c0c0d; }
.dv-head-row { display: flex; align-items: baseline; justify-content: space-between; gap: 20px; }
.dv-band > .dv-head-row { margin-bottom: 26px; }

/* -------------------------------------------------------------------- Hero
   A rail of four, centred, with the edges of the last and the next showing —
   so it reads as a place you can move through rather than a banner that
   changes on its own. It does change on its own; dev.js drives it, and the
   pause beside the dots stops it for good. */
.dv-hero { padding: 18px 0 0; }
.dv-hero-track {
  --dv-card: clamp(280px, 62vw, 1000px);
  display: flex; gap: 22px;
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scroll-behavior: smooth;
  padding: 0 calc((100% - var(--dv-card)) / 2);
  scrollbar-width: none;
}
.dv-hero-track::-webkit-scrollbar { display: none; }
@media (prefers-reduced-motion: reduce) { .dv-hero-track { scroll-behavior: auto; } }

.dv-slide {
  position: relative; flex: 0 0 var(--dv-card);
  aspect-ratio: 9 / 5; scroll-snap-align: center;
  border-radius: 0; overflow: hidden; background: #1d1d1f;
}
.dv-slide > .dv-media { position: absolute; inset: 0; }
.dv-slide-copy {
  position: absolute; left: 0; right: 0; bottom: clamp(18px, 3vw, 30px);
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
  gap: 10px 14px; padding: 0 22px; text-align: center;
}
.dv-slide-copy p { font-size: clamp(13px, 1.3vw, 16px); line-height: 1.4; color: var(--dv-ink); }
.dv-slide-copy b { font-weight: 600; }
.dv-slide-copy .dot { color: var(--dv-ink-2); padding: 0 2px; }
.dv-pill {
  flex: none; padding: 8px 16px; border-radius: 100px;
  background: #fff; color: #1d1d1f;
  font-size: 13px; line-height: 1; font-weight: 500; white-space: nowrap;
  transition: background .2s var(--dv-ease);
}
.dv-pill:hover { background: rgba(255, 255, 255, .85); }
/* The two slides either side are there to show there is more, not to be read. */
.dv-slide:not(.is-on) .dv-slide-copy { opacity: 0; transition: opacity .3s var(--dv-ease); }
.dv-slide.is-on .dv-slide-copy { opacity: 1; transition: opacity .45s var(--dv-ease) .1s; }

.dv-hero-ctl { display: flex; align-items: center; justify-content: center; gap: 14px; padding: 22px 0 0; }
.dv-dots {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 14px; border-radius: 100px; background: #1d1d1f;
}
.dv-dot {
  position: relative; width: 7px; height: 7px; border-radius: 100px;
  background: rgba(255, 255, 255, .3); overflow: hidden;
  transition: width .4s var(--dv-ease), background .4s var(--dv-ease);
}
.dv-dot:hover { background: rgba(255, 255, 255, .5); }
.dv-dot.is-on { width: 34px; background: rgba(255, 255, 255, .3); }
/* The fill is the clock: it crosses the dot over one slide's turn, so the
   carousel says how long you have rather than moving without warning. */
.dv-dot .fill {
  position: absolute; inset: 0; width: 0; border-radius: inherit;
  background: #f5f5f7;
}
.dv-dot.is-on .fill { width: 100%; transition: width var(--dv-turn, 6s) linear; }
.dv-dot.is-on.is-held .fill { transition: none; }
.dv-pause {
  flex: none; display: grid; place-items: center;
  width: 32px; height: 32px; border-radius: 100px; background: #1d1d1f;
  color: var(--dv-ink);
}
.dv-pause svg { width: 15px; height: 15px; fill: currentColor; }
.dv-pause .r, .dv-pause[aria-pressed="true"] .p { display: none; }
.dv-pause[aria-pressed="true"] .r { display: block; }

/* -------------------------------------------------------------------- Rails */
.dv-rail {
  /* The rail runs the full width of the window but starts where the heading
     above it starts. scroll-padding as well as padding: a snap point is
     measured from the scrollport's *padding* edge, so without it the first
     card snaps flush to the window and cancels the inset the moment anybody
     touches the rail. */
  --dv-inset: max(22px, calc((100% - var(--dv-wrap)) / 2));
  display: flex; gap: 14px;
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-behavior: smooth;
  padding: 4px var(--dv-inset);
  scroll-padding-inline: var(--dv-inset);
  scrollbar-width: none;
}
/* No snapping here, unlike the hero. A rail's last card sits past the last
   snap point that fits, and a mandatory snap then drags the scroll back off
   the end — the card can be reached and not stayed on, and the "next" arrow
   never goes dim. The arrows page it and a trackpad scrolls it freely, which
   is all a strip of cards needs. scroll-padding stays: it is what keeps a
   card tabbed to from landing under the left edge. */
.dv-rail::-webkit-scrollbar { display: none; }
@media (prefers-reduced-motion: reduce) { .dv-rail { scroll-behavior: auto; } }

.dv-rail-ctl { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-top: 22px; }
.dv-arrows { display: flex; gap: 10px; }
.dv-arrows button {
  display: grid; place-items: center; width: 34px; height: 34px;
  border-radius: 100px; background: #1d1d1f; color: var(--dv-ink);
  transition: background .2s var(--dv-ease), opacity .2s var(--dv-ease);
}
.dv-arrows button svg { width: 14px; height: 14px; }
.dv-arrows button:hover { background: #2a2a2d; }
.dv-arrows button[disabled] { opacity: .32; cursor: default; }
.dv-flat {
  padding: 8px 16px; border-radius: 100px; background: #1d1d1f;
  font-size: 13px; line-height: 1; color: var(--dv-ink);
  transition: background .2s var(--dv-ease);
}
a.dv-flat:hover { background: #2a2a2d; }
.dv-flat.is-quiet { background: none; padding-left: 0; color: var(--dv-ink-3); }

/* A card in the "start" rail. Apple puts a date here; we put what is true. */
.dv-note {
  flex: 0 0 clamp(230px, 24vw, 264px);
  display: flex; flex-direction: column; gap: 12px;
  padding: 18px 18px 20px; border-radius: 14px; background: var(--dv-panel);
}
.dv-note h3 { font-size: 16px; font-weight: 600; line-height: 1.25; letter-spacing: -.01em; }
.dv-note p { font-size: 13px; line-height: 1.45; color: var(--dv-ink-2); }
.dv-note-meta { margin-top: auto; padding-top: 8px; font-size: 12px; line-height: 1.45; color: var(--dv-ink-3); }
.dv-badge {
  align-self: flex-start; padding: 4px 9px; border-radius: 6px;
  background: rgba(255, 255, 255, .08); color: var(--dv-ink-2);
  font-size: 11px; line-height: 1.3; letter-spacing: 0;
}
.dv-badge.is-open { background: rgba(41, 151, 255, .16); color: var(--dv-blue); }
.dv-badge.is-ask { background: rgba(255, 255, 255, .13); color: var(--dv-ink); }

/* A film card. */
.dv-film { flex: 0 0 clamp(240px, 26vw, 288px); }
.dv-film-btn { position: relative; display: block; width: 100%; }
.dv-film-btn .dv-media { aspect-ratio: 16 / 9; border-radius: 10px; }
.dv-film-tag {
  position: absolute; left: 8px; bottom: 8px;
  padding: 3px 7px; border-radius: 5px; background: rgba(0, 0, 0, .55);
  font-size: 10.5px; letter-spacing: 0; color: rgba(255, 255, 255, .92);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.dv-film-play {
  position: absolute; inset: 0; display: grid; place-items: center;
  opacity: 0; transition: opacity .2s var(--dv-ease);
}
.dv-film-play svg { width: 44px; height: 44px; fill: #fff; filter: drop-shadow(0 2px 10px rgba(0, 0, 0, .5)); }
.dv-film-btn:hover .dv-film-play, .dv-film-btn:focus-visible .dv-film-play { opacity: 1; }
.dv-film h3 { margin-top: 11px; font-size: 13.5px; font-weight: 400; line-height: 1.4; color: var(--dv-ink); }

/* ------------------------------------------------------------------ For you
   The one place the page glows. A ring that runs blue to violet, the same
   family as the band at the bottom, so the colour on this page is spent once
   and in one direction. */
.dv-foryou .dv-h2 { margin-bottom: 22px; }
/* The ring is one square of conic gradient, turning behind a panel that is
   two pixels smaller on every side. Square, and wider than the panel, because
   a conic gradient stretched into a long thin box paints horizontal bands
   rather than a light going round. The bloom outside is the element's own
   box-shadow, which its overflow does not clip. */
.dv-glow {
  position: relative; padding: 2px; border-radius: 18px; overflow: hidden;
  box-shadow: 0 0 56px -12px rgba(94, 92, 230, .55);
}
.dv-glow::before {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 150%; aspect-ratio: 1; transform: translate(-50%, -50%);
  background: conic-gradient(from 0deg, #2997ff, #5e5ce6, #bf5af2, #ff375f, #ff9f0a, #2997ff);
  animation: dv-turn 9s linear infinite;
}
@keyframes dv-turn {
  from { transform: translate(-50%, -50%) rotate(0turn); }
  to   { transform: translate(-50%, -50%) rotate(1turn); }
}
@media (prefers-reduced-motion: reduce) { .dv-glow::before { animation: none; } }
.dv-glow-in {
  position: relative; z-index: 1; border-radius: 16px; background: #0d0d0e;
  padding: clamp(34px, 5vw, 52px) 26px; text-align: center;
}
.dv-glow-in p { font-size: 15px; color: var(--dv-ink-2); max-width: 44ch; margin: 0 auto; }
.dv-glow-in .dv-btn { margin-right: 0; }

/* ---------------------------------------------------------------- Platforms */
.dv-band > .dv-wrap > .dv-h2 { margin-bottom: 26px; }
.dv-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.dv-plat {
  display: flex; flex-direction: column;
  border-radius: 16px; background: var(--dv-panel); overflow: hidden;
  padding: 30px 24px 0; min-height: 340px;
}
.dv-plat header { text-align: center; }
.dv-plat h3 { font-family: var(--dv-display); font-size: clamp(22px, 2.4vw, 28px); font-weight: 600; letter-spacing: -.003em; }
.dv-plat h3 span { font-weight: 400; color: var(--dv-ink-2); }
.dv-plat header p { margin-top: 6px; font-size: 12.5px; color: var(--dv-ink-3); }
.dv-plat > .dv-media { flex: 1 1 auto; margin-top: 22px; min-height: 180px; }

.dv-wide {
  margin-top: 14px; padding: clamp(40px, 6vw, 64px) 26px;
  border-radius: 16px; background: var(--dv-panel); text-align: center;
}
.dv-wide .dv-mark { width: 104px; height: 104px; margin: 0 auto 20px; border-radius: 22px; }
.dv-wide h3 { font-family: var(--dv-display); font-size: clamp(24px, 2.6vw, 30px); font-weight: 600; letter-spacing: -.003em; }
.dv-wide p { margin: 12px auto 0; max-width: 44ch; font-size: 15px; color: var(--dv-ink-2); }
.dv-wide .dv-link { margin-top: 16px; }

/* ------------------------------------------------------------- Technologies */
.dv-cols { display: grid; grid-template-columns: repeat(4, 1fr); gap: 28px; margin-top: 40px; }
.dv-col h3 { font-size: 12px; font-weight: 600; letter-spacing: .01em; color: var(--dv-ink-3); text-transform: uppercase; }
.dv-col ul { margin-top: 12px; display: grid; gap: 9px; }
.dv-col li { font-size: 14px; color: var(--dv-ink-2); }

/* -------------------------------------------------------------- Split rows */
.dv-split { display: grid; grid-template-columns: 1fr 1fr; align-items: center; gap: clamp(30px, 5vw, 60px); }
.dv-split .dv-media { aspect-ratio: 4 / 3; border-radius: 18px; }
.dv-split.is-flip .dv-split-copy { order: 1; }

/* --------------------------------------------------------------- Cell grid */
.dv-grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-top: 30px; }
.dv-cell { padding: 26px 22px 28px; border-radius: 14px; background: var(--dv-panel); }
.dv-cell h3 { font-size: 18px; font-weight: 600; letter-spacing: -.01em; }
.dv-cell p { margin-top: 10px; font-size: 14px; line-height: 1.5; color: var(--dv-ink-2); }

/* ------------------------------------------------------- Developer Program */
.dv-program {
  padding: clamp(56px, 8vw, 92px) 0; text-align: center;
  background: linear-gradient(105deg, #ff2d78 0%, #9b3ff0 38%, #5e5ce6 68%, #2997ff 100%);
  color: #fff;
}
.dv-program-mark { width: 74px; height: auto; margin: 0 auto 22px; }
.dv-program h2 { font-family: var(--dv-display); font-size: clamp(26px, 3.2vw, 38px); font-weight: 600; letter-spacing: -.003em; }
.dv-program p { margin: 14px auto 0; max-width: 60ch; font-size: 15.5px; line-height: 1.55; color: rgba(255, 255, 255, .92); }

/* -------------------------------------------------------------- The footer
   The site's own footer, on black. Its tokens come from oplo-chrome.css; this
   only turns the ground over, because the site's footer sits on white. */
.dv .foot { background: #000; color: var(--dv-ink-2); }
.dv .foot { --paper: #000; --ink: #f5f5f7; --ink-2: #a1a1a6; --ink-3: #86868b; --rule: rgba(255, 255, 255, .16); --blue: #2997ff; }
.dv .notes { background: #000; }
/* The summary that folds the notes on a phone. The site keeps these rules in
   its "Phone: less of it" block, which is not one of the sections cut into
   oplo-chrome.css — cutting it would drag in rules for pages that are not
   here. It is four declarations; say them. */
.dv .notes-d > summary { list-style: none; }
.dv .notes-d > summary::-webkit-details-marker { display: none; }
@media (min-width: 735px) { .dv .notes-d > summary { display: none; } }
@media (max-width: 734px) {
  .dv .notes { padding: 2px 0 4px; }
  .dv .notes-d > summary {
    display: flex; align-items: center; justify-content: space-between;
    max-width: 1024px; margin-inline: auto; padding: 14px 22px;
    font-size: 12px; font-weight: 600; color: var(--dv-ink); cursor: pointer;
  }
  .dv .notes-d > summary::after {
    content: ""; width: 7px; height: 7px; margin-right: 4px;
    border-right: 1px solid var(--dv-ink-2); border-bottom: 1px solid var(--dv-ink-2);
    transform: translateY(-2px) rotate(45deg); transition: transform .25s var(--dv-ease);
  }
  .dv .notes-d[open] > summary::after { transform: translateY(2px) rotate(225deg); }
  .dv .notes-d > ol { padding-bottom: 14px; }
}

/* ----------------------------------------------------------------- The film */
.dv-film-box { position: fixed; inset: 0; z-index: 9500; display: grid; place-items: center; }
.dv-film-box[hidden] { display: none; }
.dv-film-scrim { position: absolute; inset: 0; background: rgba(0, 0, 0, .86); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); }
.dv-film-stage { position: relative; width: min(1100px, calc(100% - 48px)); }
.dv-film-stage video { width: 100%; border-radius: 14px; background: #000; display: block; }
.dv-film-stage video[hidden] { display: none; }
.dv-film-none { padding: 46px 30px; border-radius: 14px; background: #1d1d1f; text-align: center; font-size: 14px; color: var(--dv-ink-2); }
.dv-film-none[hidden] { display: none; }
.dv-film-none code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; color: var(--dv-ink); }
.dv-film-close {
  position: absolute; top: -42px; right: 0;
  display: grid; place-items: center; width: 30px; height: 30px;
  border-radius: 100px; background: rgba(255, 255, 255, .14); color: #fff;
}
.dv-film-close svg { width: 12px; height: 12px; }

/* ------------------------------------------------------------ Reveal
   Fails open: everything is visible until the script arms it, so a page with
   no JavaScript is a page with all its content. */
.dv-armed .dv-rise { opacity: 0; transform: translateY(18px); }
.dv-armed .dv-rise.is-in { opacity: 1; transform: none; transition: opacity .7s var(--dv-ease), transform .7s var(--dv-ease); }
@media (prefers-reduced-motion: reduce) {
  .dv-armed .dv-rise { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------------ Narrow */
@media (max-width: 900px) {
  .dv-cols { grid-template-columns: 1fr 1fr; gap: 24px 28px; }
  .dv-grid3 { grid-template-columns: 1fr; }
  .dv-split { grid-template-columns: 1fr; }
  .dv-split.is-flip .dv-split-copy { order: 0; }
  .dv-split .dv-media { order: -1; }
  .dv-plat { min-height: 280px; }
}
@media (max-width: 734px) {
  .dv { font-size: 16px; }
  .dv-wrap { width: calc(100% - 40px); }
  .dv-hero-track { --dv-card: 88vw; gap: 12px; }
  .dv-slide { aspect-ratio: 4 / 3; }
  .dv-grid2 { grid-template-columns: 1fr; }
  .dv-cols { grid-template-columns: 1fr; }
  .dv-rail { --dv-inset: 20px; }
  .dv-rail-ctl { flex-wrap: wrap; }
}
