/* Odisal Site: the parts of the home page Elementor's free panel can't set.
   Colours, sizes and text live in Elementor; device frames, the overlapping
   hero and the fanned invoices live here. */

:root {
  /* Motion curves. Taken from Emil Kowalski's standards, not hand-rolled:
     a strong ease-out for things arriving, a strong ease-in-out for things
     moving on screen. */
  --od-ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --od-ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --od-sans: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Inter', 'Helvetica Neue', sans-serif;
  --od-link: #0066CC;
}

html { scroll-behavior: smooth; }
body.od-site { -webkit-font-smoothing: antialiased; }
[id] { scroll-margin-top: 56px; }

/* Apple's own typeface on Apple devices, Inter everywhere else. */
.od,
.od .elementor-heading-title,
.od .elementor-widget-text-editor,
.od .elementor-button,
.od-header .vh-root,
.od-header .vh-root * { font-family: var(--od-sans) !important; }

.od .elementor-widget-text-editor p { margin: 0; }
/* The wordmark is always lowercase, whatever the site title says. */
.od-header .vh-logo-text, .od-header .vh-plogo { text-transform: lowercase; }
.od-sub p { max-width: 720px; margin: 6px auto 0 !important; }
.od-small { margin-top: 14px; }
.od-more a { color: var(--od-link); text-decoration: none; }
@media (hover: hover) and (pointer: fine) { .od-more a:hover { text-decoration: underline; } }
.od a:focus-visible { outline: 2px solid var(--od-link); outline-offset: 3px; border-radius: 4px; }

/* Screenshots in a plain browser window. */
.od-browser { width: 100%; max-width: 980px !important; margin: 56px auto 0; border-radius: 14px 14px 0 0; overflow: hidden; background: #ECEAE4; padding-top: 32px; position: relative;
  box-shadow: 0 30px 80px -30px rgba(60, 40, 10, .35), 0 0 0 1px rgba(0, 0, 0, .06); }
.od-browser::before { content: ""; position: absolute; top: 11px; left: 14px; width: 47px; height: 11px;
  background: radial-gradient(circle at 5.5px 5.5px, #D5D2CA 5.5px, transparent 6px) 0 0 / 18px 11px repeat-x; }
.od-browser.od-round { border-radius: 14px; }
.od .od-browser img { display: block; width: 100%; height: auto; border-radius: 0 !important; }

/* Screenshots in an iPhone. */
.od-phone { width: 270px !important; max-width: 100%; flex: none; border-radius: 50px; background: #111; padding: 9px;
  box-shadow: 0 0 0 1.5px #3a3a3c inset, 0 40px 80px -30px rgba(31, 38, 64, .55); }
/* Elementor resets `border-radius` on every image it renders, with a rule
   that can load after this file. These corners are part of the picture, not
   a preference, so they are stated in a way that cannot be reset. */
.od .od-phone img { display: block; width: 100%; height: auto; border-radius: 42px !important; }
.od-phones .od-phone { width: 260px !important; }
.od-phones .od-phone-main { width: 290px !important; }

/* Hero: the laptop window with the phone in front. */
.od-duo { position: relative; max-width: 1060px; width: 100%; margin: 64px auto 0; }
.od-duo .od-browser { width: 84% !important; margin: 0; }
.od-duo .od-duo-phone { position: absolute !important; right: 0; bottom: -60px; width: 250px !important; }
.od-label .od-more { margin-top: 2px; }

/* Three invoices fanned out. */
.od-fan { max-width: 1000px; margin: 64px auto 0; }
.od-fan .od-doc { width: 34% !important; flex: none; }
.od .od-fan .od-doc img { display: block; width: 100%; height: auto; border-radius: 8px 8px 0 0 !important; background: #fff;
  box-shadow: 0 20px 50px -18px rgba(0, 0, 0, .28), 0 0 0 1px rgba(0, 0, 0, .05); }
.od-fan .od-doc:nth-child(1) { transform: translateX(24px) rotate(-4deg) translateY(30px); }
.od-fan .od-doc:nth-child(2) { width: 36% !important; position: relative; z-index: 1; }
.od-fan .od-doc:nth-child(3) { transform: translateX(-24px) rotate(4deg) translateY(30px); }

/* Half-width panels: picture sits at the bottom edge. */
.od-half { min-height: 620px; overflow: hidden; }
.od-half > .e-con-inner, .od-half { justify-content: flex-start; }
.od-half .od-card, .od-half .od-half-phone { margin-top: auto !important; }
.od-half .od-card { width: 100%; max-width: 520px !important; }
.od .od-half .od-card img { display: block; width: 100%; height: auto; border-radius: 12px 12px 0 0 !important;
  box-shadow: 0 20px 50px -20px rgba(0, 0, 0, .25), 0 0 0 1px rgba(0, 0, 0, .06); }
/* Runs off the bottom of its panel. Done with a margin, not a transform: an
   entrance animation ends by setting the transform, and would undo it. */
.od-half .od-half-phone { width: 260px !important; margin-top: 48px !important; margin-bottom: -90px !important; }

.od-foot-note { padding-bottom: 12px; border-bottom: 1px solid #D2D2D7; }
.od-foot a { color: #424245; text-decoration: none; }
@media (hover: hover) and (pointer: fine) { .od-foot a:hover { text-decoration: underline; } }

@media (max-width: 767px) {
  .od-browser { margin-top: 40px; border-radius: 10px 10px 0 0; }
  .od-duo { margin-top: 40px; }
  .od-duo .od-browser { width: 100% !important; }
  .od-duo .od-duo-phone { width: 120px !important; border-radius: 24px; padding: 4px; right: -6px; bottom: -30px; }
  .od .od-duo .od-duo-phone img { border-radius: 20px !important; }
  /* All three invoices on a phone too: narrower, overlapping a little more,
     the middle one in front. Shifts are in % of each invoice's own width. */
  /* One row, never wrapped: Elementor lets containers wrap on phones. */
  .od-fan { margin-top: 40px; --flex-wrap: nowrap; flex-wrap: nowrap !important; }
  .od-fan .od-doc { width: 38% !important; }
  .od-fan .od-doc:nth-child(2) { width: 42% !important; }
  .od-fan .od-doc:nth-child(1) { transform: translateX(22%) rotate(-5deg) translateY(14px); }
  .od-fan .od-doc:nth-child(3) { transform: translateX(-22%) rotate(5deg) translateY(14px); }
  .od .od-fan .od-doc img { border-radius: 5px 5px 0 0 !important; }
  .od-phones .od-phone:not(.od-phone-main) { display: none; }
  .od-phones .od-phone-main { width: 250px !important; }
  .od-half { min-height: 560px; }
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* Inter, served from this site. Loading it from Google would tell Google
   about every visitor, and the privacy policy says no third party is told. */
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 400; font-display: swap; src: url(fonts/inter-latin-400-normal.woff2) format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap; src: url(fonts/inter-latin-600-normal.woff2) format('woff2'); }

/* Long-form pages: privacy and support. One readable column. */
.od-prose { margin-top: 48px; text-align: left; }
.od-prose .od-updated { color: #6E6E73; font-size: 14px; }
.od-prose h2 { font: 600 28px/1.15 var(--od-sans); letter-spacing: -.02em; margin: 56px 0 12px; color: #1D1D1F; }
.od-prose h3 { font: 600 19px/1.3 var(--od-sans); letter-spacing: -.015em; margin: 32px 0 6px; color: #1D1D1F; }
.od .od-prose p { margin: 0 0 14px !important; }
.od-prose ul { margin: 0 0 14px; padding-left: 22px; }
.od-prose li { margin-bottom: 8px; }
.od-prose a { color: var(--od-link); text-decoration: none; }
@media (hover: hover) and (pointer: fine) { .od-prose a:hover { text-decoration: underline; } }
.od-prose table { width: 100%; border-collapse: collapse; margin: 8px 0 20px; font-size: 15px; }
.od-prose th, .od-prose td { text-align: left; vertical-align: top; padding: 12px 14px 12px 0; border: 0; border-bottom: 1px solid #D2D2D7; background: none !important; }
.od-prose th { font-weight: 600; color: #6E6E73; font-size: 13px; }
@media (max-width: 767px) {
  .od-prose { margin-top: 36px; }
  .od-prose h2 { font-size: 24px; margin-top: 44px; }
  .od-prose table, .od-prose tbody, .od-prose tr, .od-prose td { display: block; }
  .od-prose th { display: none; }
  .od-prose tr { padding: 12px 0; border-bottom: 1px solid #D2D2D7; }
  .od-prose td { border: 0; padding: 2px 0; }
  .od-prose td:first-child { font-weight: 600; }
}

/* Home: the wordmark as the whole first screen. The heading keeps its text
   ("odisal") for search and screen readers; what shows is the drawn wordmark
   (assets/wordmark-white.svg, from source/make-wordmark.mjs). */
.od .od-wordmark .elementor-heading-title { letter-spacing: -.045em !important; }
.od-home-hero .od-wordmark .elementor-heading-title {
  display: block; width: min(80vw, 540px); aspect-ratio: 1062 / 277; margin: 0 auto clamp(18px, 3.2vw, 34px) !important;
  font-size: 0 !important; line-height: 0 !important; color: transparent !important;
  background: url(wordmark-white.svg) center / 100% 100% no-repeat; }
/* "letters": odisal.js cuts it into one span per letter, each showing its own slice of the same picture. */
.od-home-hero .od-wordmark .od-word[aria-label] { display: flex !important; background: none; }
.od-home-hero .od-wordmark .od-word span { flex: none; height: 100%; background-image: url(wordmark-white.svg); background-repeat: no-repeat; }
.od-hero-letters .od-home-hero .od-wordmark .od-word span { translate: 0 24%; }
.od-home-hero .od-sub p { margin-top: 10px !important; }

/* Home: one card per app. */
.od-app { text-align: center; }
.od-app .od-app-icon { width: 88px !important; margin-bottom: 22px; }
.od .od-app .od-app-icon img { display: block; width: 88px; height: 88px; border-radius: 20px !important; }
.od-app .od-app-status { margin-top: 6px; }
.od-app .od-sub p { margin-top: 14px !important; max-width: 380px; }
.od-app .od-app-more { margin-top: 18px; }
/* The whole card opens the app's page. Its one link, "Learn more", is
   stretched over the card, so there are no links inside links and a screen
   reader still hears a single link per app. */
.od-app { position: relative; cursor: pointer; transition: transform 160ms var(--od-ease-out); }
.od-app .od-app-more, .od-app .od-app-more * { position: static !important; }
.od-app .od-app-more a::after { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; }
.od-app:active { transform: scale(.985); }
.od-app:has(.od-app-more a:focus-visible) { outline: 2px solid var(--od-link); outline-offset: 4px; }
.od-app .od-app-more a:focus-visible { outline: 0; }
@media (hover: hover) and (pointer: fine) { .od-app:hover .od-app-more a { text-decoration: underline; } }
/* A card that is also arriving keeps its arrival and adds the press. */
:root.od-motion .od-app.od-reveal {
  transition: opacity calc(500ms * var(--od-t, 1)) var(--od-ease-out), translate calc(700ms * var(--od-t, 1)) var(--od-ease-out),
    scale calc(700ms * var(--od-t, 1)) var(--od-ease-out), transform 160ms var(--od-ease-out);
  transition-delay: calc(var(--n, 0) * 60ms), calc(var(--n, 0) * 60ms), calc(var(--n, 0) * 60ms), 0ms; }

/* ---------- Motion ----------
   Chosen in Tools > Odisal pages (or the live editor) and applied by
   odisal.js. All of it sits under `.od-motion`, which is only set when motion
   is wanted; `--od-t` is the chosen speed (1 = normal). `translate` and
   `scale` are used rather than `transform` so they add to the transforms the
   layout already uses. Arrivals use the strong ease-out; things moving on
   screen use ease-in-out. Visitors who ask for less motion get `.od-calm`:
   the same arrivals as plain fades, with nothing travelling. */

/* Home hero. "letters": the wordmark a letter at a time (60ms apart), then
   the line and the button. "fade": the same three, each as a whole. Runs
   once per visit, so it may take its time; CSS keyframes keep it smooth while
   the page is still loading. */
.od-hero-letters .od-wordmark .od-word:not([aria-label]),
.od-hero-letters .od-wordmark :is(h1, .elementor-heading-title):not(.od-word) { opacity: 0; }
.od-hero-letters .od-word span { display: inline-block; opacity: 0; translate: 0 .24em;
  animation: od-rise calc(700ms * var(--od-t, 1)) var(--od-ease-out) forwards;
  animation-delay: calc(var(--i) * 60ms + 100ms); }
.od-hero-fade .od-home-hero .od-wordmark { opacity: 0; translate: 0 12px;
  animation: od-rise calc(700ms * var(--od-t, 1)) var(--od-ease-out) 100ms forwards; }
:is(.od-hero-letters, .od-hero-fade) .od-home-hero :is(.od-sub, .elementor-widget-button) { opacity: 0; translate: 0 12px;
  animation: od-rise calc(500ms * (.5 + .5 * var(--od-t, 1))) var(--od-ease-out) forwards; }
/* The line and the button follow the wordmark without waiting for it to
   finish: the main action is never hidden for long, whatever the speed. */
:is(.od-hero-letters, .od-hero-fade) .od-home-hero .od-sub { animation-delay: 400ms; }
:is(.od-hero-letters, .od-hero-fade) .od-home-hero .elementor-widget-button { animation-delay: 500ms; pointer-events: none; }
/* pointer-events switches halfway through, so a button can't be pressed while it is still invisible. */
@keyframes od-rise { to { opacity: 1; translate: 0 0; pointer-events: auto; } }
@keyframes od-fade { to { opacity: 1; pointer-events: auto; } }
.od-calm :is(.od-wordmark, .od-sub, .elementor-widget-button) { translate: 0 0 !important; animation-name: od-fade !important; }

/* The hero receding as the page scrolls is set on the element itself by
   odisal.js, not through a variable on its parent, so only it is restyled. */

/* Arrivals: app cards, windows, phones and panel pictures. Small distances,
   because the eye only needs to be told where something came from. A slide
   starts to one side, so sections clip sideways and the page never scrolls
   horizontally because of one. */
.od-tile, .od-pair, .od-half { overflow-x: clip !important; }
body.od-site { overflow-x: clip; }
/* `:root` lifts these above Elementor 4's own transition on every widget
   (.elementor-element:not(:has(.elementor-widget-container))), which loads
   later and would otherwise make screenshots appear without moving. */
:root.od-motion .od-reveal { opacity: 0;
  transition: opacity calc(500ms * var(--od-t, 1)) var(--od-ease-out), translate calc(700ms * var(--od-t, 1)) var(--od-ease-out), scale calc(700ms * var(--od-t, 1)) var(--od-ease-out);
  /* The gap between items in a row stays 60ms; only each item's own movement follows Speed. */
  transition-delay: calc(var(--n, 0) * 60ms); }
.od-motion .od-reveal[data-fx="rise"] { translate: 0 24px; }
.od-motion .od-reveal[data-fx="slide"][data-from="left"] { translate: -48px 0; }
.od-motion .od-reveal[data-fx="slide"][data-from="right"] { translate: 48px 0; }
.od-motion .od-reveal[data-fx="zoom"] { scale: .95; }
/* Written to outrank every starting state above, whichever effect is chosen. */
.od-motion .od-reveal.od-in[data-fx][data-from] { opacity: 1; translate: 0 0; scale: 1; }

/* The three invoices start as one pile and fan out: movement on screen, so
   ease-in-out. */
:root.od-motion .od-fan-fx .od-doc { transition: transform calc(800ms * var(--od-t, 1)) var(--od-ease-in-out) 100ms; }
.od-motion .od-fan-fx:not(.od-in) .od-doc:nth-child(1) { transform: translateX(92%) translateY(30px); }
.od-motion .od-fan-fx:not(.od-in) .od-doc:nth-child(3) { transform: translateX(-92%) translateY(30px); }

/* Buttons answer a press. Elementor gives them `transition: all`, which is
   narrowed here to what actually changes. */
.od .elementor-button { transition: scale 160ms var(--od-ease-out), background-color 200ms ease, color 200ms ease, border-color 200ms ease !important; }
.od .elementor-button:active { scale: .97; }
/* Hover, with a mouse only: on a touch screen a tapped button would keep its
   hover colours until the next tap elsewhere. Elementor's own hover colours
   are set to match the normal ones, so these are the only ones. */
@media (hover: hover) and (pointer: fine) {
  .od .od-btn-fill .elementor-button:hover { background-color: #000 !important; border-color: #000 !important; }
  .od .od-btn-ghost.od-btn-ink .elementor-button:hover { background-color: #1D1D1F !important; color: #FFF !important; }
  .od .od-btn-ghost.od-btn-navy .elementor-button:hover { background-color: #1F2640 !important; color: #FFF !important; }
  .od .od-btn-light .elementor-button:hover { background-color: #E8E8ED !important; border-color: #E8E8ED !important; }
}

/* An app's icon lifts when its card is pointed at, with a mouse only:
   touch screens report a hover on tap. */
.od-app .od-app-icon img { transition: scale 200ms ease, box-shadow 200ms ease; }
@media (hover: hover) and (pointer: fine) {
  .od-app:hover .od-app-icon img { scale: 1.05; box-shadow: 0 14px 30px -12px rgba(0, 0, 0, .35); }
}

/* No frosted header: blurring everything that scrolls beneath it on every
   frame made scrolling stutter on iPhone (1.8.0). The bar stays a plain,
   nearly opaque white, set in the header widget. */

/* ---------- Pinned stories ----------
   By default this is a plain list: each step is a heading, a line and its
   picture. With `.od-story-on` (set by odisal.js on wide screens when the
   effect is chosen) the pictures leave the steps and one frame is pinned
   beside them, showing the picture of whichever step is passing. */
.od-story-win { width: 100%; max-width: 460px; border-radius: 14px; overflow: hidden; background: #fff;
  box-shadow: 0 30px 70px -30px rgba(60, 40, 10, .4), 0 0 0 1px rgba(0, 0, 0, .06); }
.od .od-story-win img { display: block; width: 100%; height: auto; border-radius: 0 !important; }
.od-story-stage-col { display: none !important; }
.od-story-step { padding: 28px 0; }
.od-story-step .od-story-inline { margin-top: 26px; }
.od-story-step .od-story-inline.od-phone { width: 250px !important; }
.od-story-text p { max-width: 460px; }

.od-story-on .od-story-stage-col { display: flex !important; align-self: flex-start; position: sticky; top: 0; height: 100svh; align-items: center; justify-content: center; }
/* The frame's pictures are stacked absolutely, so nothing inside gives the
   column a width: it is given one. */
.od-story-on .od-story-stage-col > * { width: 100%; }
.od-story-on .od-story-stage { display: flex; justify-content: center; width: 100%; }
.od-story-on .od-story-stage > div { position: relative; }
.od-story-on .od-story-stage .od-story-win { aspect-ratio: 1 / 1; max-width: 480px; }
.od-story-on .od-story-stage img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top center; opacity: 0;
  /* Which picture shows follows the reader's position, so it swaps at a
     fixed 300ms; only the gentle settle in scale follows Speed. */
  transition: opacity 300ms var(--od-ease-out), scale calc(600ms * var(--od-t, 1)) var(--od-ease-out);
  scale: 1.03; }
.od-story-on .od-story-stage .od-phone { --ph: min(74vh, 620px); }
/* The story's phone, pinned (wide screens) or above the tabs (phones). The
   screen is sized, not the frame: --ph is the screen's height, its width
   follows the screenshots' own shape (736 x 1600), and the 9px bezel sits
   outside it. Sizing the frame instead squeezed the screen into a different
   shape, so the screenshot was cropped at the sides. Corners scale with the
   width, as on a real iPhone, so a small phone never turns into a capsule. */
:is(.od-story-on, .od-story-tabs) .od-story-stage .od-phone { box-sizing: content-box; aspect-ratio: auto;
  height: var(--ph); width: calc(var(--ph) * 0.46) !important; border-radius: calc(var(--ph) * 0.46 * 0.15 + 9px); }
:is(.od-story-on, .od-story-tabs) .od .od-story-stage .od-phone img { inset: 9px; width: calc(100% - 18px); height: calc(100% - 18px);
  object-fit: cover; border-radius: calc(var(--ph) * 0.46 * 0.15) !important; }
/* A plain crossfade. 1.8.0 blurred the outgoing picture, which kept three
   large screenshots behind a blur filter and made iPhone scrolling stutter. */
.od-story-on .od-story-stage img.on { opacity: 1; scale: 1; }
.od-calm .od-story-stage img { scale: 1 !important; }
.od-story-on .od-story-inline { display: none !important; }
.od-story-on .od-story-step { min-height: 72vh; padding: 0; justify-content: center; opacity: .22; transition: opacity 250ms ease; }
.od-story-on .od-story-step.on { opacity: 1; }
.od-story-on .od-story-steps { padding: 14vh 0; }

/* ---------- On a phone ----------
   The small fixes that stop the site feeling like a web page in a browser. */

/* No grey flash over whatever is tapped, and no text inflation in landscape.
   Every tappable thing has its own press state instead. */
body.od-site { -webkit-tap-highlight-color: transparent; -webkit-text-size-adjust: 100%; }

/* Controls answer the tap at once (no wait for a possible double tap), and a
   long press doesn't select their label. Body text stays selectable. */
.od .elementor-button, .od-app-more a, .od-header .vh-root a, .od-header .vh-root button {
  touch-action: manipulation; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.od-app-more a { transition: opacity 120ms var(--od-ease-out); }
.od-app-more a:active { opacity: .55; }

/* The hero is sized to the smallest the screen gets, so the browser's bars
   never push the button off the bottom of the first screen. */
.od-home-hero { --min-height: 92svh !important; min-height: 92svh !important; }

/* ---------- Type ----------
   Tracking tightens as headings grow and stays near zero for reading text,
   set in em so it scales with each size, phone or desktop. Headings break
   into even lines; paragraphs avoid a single word on the last line. */
.od :is(h1, h2).elementor-heading-title { letter-spacing: -.025em !important; text-wrap: balance; }
.od h3.elementor-heading-title { letter-spacing: -.018em !important; text-wrap: balance; }
.od .od-sub p { letter-spacing: -.012em !important; text-wrap: balance; }
.od .elementor-widget-text-editor p { text-wrap: pretty; }

/* Keyboard users see where they are, on buttons as on links. */
.od .elementor-button:focus-visible { outline: 2px solid var(--od-link); outline-offset: 3px; }

/* ---------- Header ----------
   Solid white. Without a blur behind it (removed in 1.8.1 for speed), a
   see-through bar let the page show through its text and turned grey over
   the black hero. */
.od-header .vh-bar { background-color: #fff !important; }

/* ---------- Feature steps on phones and tablets ----------
   Below the width where the picture pins, the steps were one long column of
   full-size screenshots. Here they become a row of cards you swipe through,
   each with its picture on top, centred like the rest of the page. The next
   card peeks in so it is clear there is more. Native scrolling and snapping,
   no script. Used when the pinned picture is switched off. */
@media (max-width: 1024px) {
  :root:not(.od-story-on):not(.od-story-tabs) .od-story-steps { flex-direction: row !important; flex-wrap: nowrap !important; gap: 14px !important;
    /* !important: Elementor sets overflow on every container, and without this
       the row cannot be swiped at all. */
    overflow-x: auto !important; overflow-y: hidden !important; scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
    margin: 0 -22px !important; width: calc(100% + 44px) !important; max-width: none !important; padding: 4px 22px 22px !important; scroll-padding: 0 22px; scrollbar-width: none; }
  :root:not(.od-story-on):not(.od-story-tabs) .od-story-steps::-webkit-scrollbar { display: none; }
  :root:not(.od-story-on):not(.od-story-tabs) .od-story-step { flex: 0 0 84% !important; width: 84% !important; max-width: 420px; scroll-snap-align: center;
    padding: 26px 20px 0 !important; border-radius: 26px !important; text-align: center; align-items: center !important; overflow: hidden; }
  :root:not(.od-story-on):not(.od-story-tabs) .od-story-kind-win .od-story-step { background: rgba(255, 255, 255, .7); }
  :root:not(.od-story-on):not(.od-story-tabs) .od-story-kind-phone .od-story-step { background: #F5F5F7; }
  :root:not(.od-story-on):not(.od-story-tabs) .od-story-step .elementor-heading-title { text-align: center; }
  :root:not(.od-story-on):not(.od-story-tabs) .od-story-text p { margin: 0 auto !important; max-width: 320px; font-size: 17px !important; line-height: 1.45 !important; }
  :root:not(.od-story-on):not(.od-story-tabs) .od-story-kind-win .od-story-step { padding-bottom: 26px !important; }
  :root:not(.od-story-on):not(.od-story-tabs) .od-story-step .od-story-inline { order: -1; margin: 0 auto 22px !important; }
  :root:not(.od-story-on):not(.od-story-tabs) .od-story-step .od-story-inline.od-phone { width: 190px !important; margin-bottom: -60px !important; order: 3; margin-top: 22px !important; }
  :root:not(.od-story-on):not(.od-story-tabs) .od-story-step .od-story-inline.od-story-win { width: 100%; }
  .od .od-story-step .od-story-win img { max-height: 360px; object-fit: cover; object-position: top center; }
  .od .od-story-step .elementor-heading-title { font-size: 26px !important; }
}

/* ---------- Feature steps as tabs on phones and tablets ----------
   Apple doesn't pin pictures on a phone; neither do we. One picture, a row of
   short tabs under it, and the text of the chosen step, all on one screen. */
.od-story-tab-label { display: none !important; }
@media (max-width: 1024px) {
  .od-story-tabs .od-story-stage-col { display: flex !important; order: 1; width: 100% !important; max-width: none !important;
    justify-content: center; padding: 0 0 20px; }
  .od-story-tabs .od-story-stage { display: flex; justify-content: center; width: 100%; }
  .od-story-tabs .od-story-stage > div { position: relative; }
  /* Big enough to read the keyboard: the phone is the point of the picture. */
  .od-story-tabs .od-story-stage .od-phone { --ph: min(64svh, 520px); }
  .od-story-tabs .od-story-stage .od-story-win { width: min(88vw, 380px); aspect-ratio: 6 / 5; }
  .od-story-tabs .od-story-stage img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top center;
    /* Answers a tap, so it stays at 200ms whatever Speed is set to. */
    opacity: 0; transition: opacity 200ms var(--od-ease-out); }
  .od-story-tabs .od-story-stage img.on { opacity: 1; }

  /* The loop of phones (odisal.js builds it and places each phone): the
     chosen one centred, its neighbours peeking in, smaller and softer. Settles
     on the iOS drawer curve; follows the finger exactly while dragged. */
  .od-story-tabs .od-story-stage:has(.od-story-view) { display: block; }
  .od-story-view { overflow: hidden; margin: 0 -22px; padding: 4px 0; touch-action: pan-y; -webkit-user-select: none; user-select: none; }
  .od-story-track { position: relative; column-gap: 14px; }
  .od-story-track > div { position: absolute !important; left: 0; top: 0; margin: 0 !important; transform-origin: 50% 60%; will-change: transform, opacity;
    transition: transform 480ms cubic-bezier(0.65, 0, 0.35, 1), opacity 480ms cubic-bezier(0.65, 0, 0.35, 1); }
  /* After a swipe: no ease-in (the phones are already moving), just a long ease-out. */
  .od-story-track[data-move="release"] > div { transition-duration: var(--od-settle, 340ms); transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1); }
  .od-story-track.od-dragging > div { transition: none; }
  .od-story-track.od-nudge > div { transition-duration: 620ms; transition-timing-function: cubic-bezier(0.65, 0, 0.35, 1); }
  .od-story-tabs .od-story-track img { opacity: 1 !important; transition: none; }

  .od-story-tabbar { order: 2; display: flex; gap: 6px; justify-content: safe center; overflow-x: auto; scrollbar-width: none;
    margin: 0 -22px; padding: 0 22px 2px; }
  .od-story-tabbar::-webkit-scrollbar { display: none; }
  .od-story-tabbar button { flex: none; appearance: none; -webkit-appearance: none; border: 0; cursor: pointer;
    background: rgba(0, 0, 0, .06); color: #1D1D1F; font: 500 15px/1 var(--od-sans); letter-spacing: -.01em;
    padding: 11px 16px; border-radius: 980px; touch-action: manipulation; -webkit-tap-highlight-color: transparent; -webkit-user-select: none; user-select: none;
    transition: background-color 200ms ease, color 200ms ease, scale 120ms var(--od-ease-out); }
  .od-story-tabbar button:active { scale: .96; }
  /* Five tabs fit a 375-390px phone; past that the row scrolls instead of being cut off. */
  @media (max-width: 430px) { .od-story-tabbar { gap: 5px; } .od-story-tabbar button { font-size: 14px; padding: 10px 11px; } }
  .od-story-tabbar button[aria-selected="true"] { background: #1D1D1F; color: #fff; }
  .od-story-tabbar button:focus-visible { outline: 2px solid var(--od-link); outline-offset: 2px; }

  .od-story-tabs .od-story-steps { order: 3; padding: 22px 0 0 !important; }
  .od-story-tabs .od-story-step { display: none !important; padding: 0 !important; text-align: center; align-items: center !important; }
  .od-story-tabs .od-story-step.on { display: flex !important; animation: od-step-in 200ms var(--od-ease-out); }
  .od-story-tabs .od-story-inline { display: none !important; }
  .od-story-tabs .od-story-step .elementor-heading-title { font-size: 26px !important; text-align: center; }
  .od-story-tabs .od-story-text, .od-story-tabs .od-story-text p { text-align: center !important; }
  .od-story-tabs .od-story-text p { margin: 0 auto !important; max-width: 330px; font-size: 17px !important; line-height: 1.45 !important; }
}
@keyframes od-step-in { from { opacity: 0; translate: 0 6px; } }
@keyframes od-step-fade { from { opacity: 0; } }
.od-calm.od-story-tabs .od-story-step.on { animation-name: od-step-fade; }
/* Reduced motion: the row still moves with the finger, but settles at once. */
.od-calm .od-story-track > div { transition-duration: 0ms !important; }

/* ---------- Product bar ----------
   The app's name and its one action under the header on the app pages, on
   phones and tablets, as on Apple's product pages. */
.od-subbar { display: none !important; }
@media (max-width: 1024px) {
  /* z-index !important: Elementor sets one on every container, and without
     this the page's pictures drew over the bar. */
  .od-subbar { display: flex !important; position: sticky !important; top: 48px; z-index: 45 !important; background-color: rgba(255, 255, 255, .96) !important; border-bottom: 1px solid rgba(0, 0, 0, .08); }
  .od .od-subbar .elementor-heading-title { letter-spacing: -.02em !important; }
  body:has(.od-subbar) [id] { scroll-margin-top: 108px; }
}

/* ---------- Phone menu ----------
   Full screen, as on Apple's site: the links are large and easy to tap,
   with the action and a line of status under them. */
.od-header .vh-panel .vh-menu a, .od-header .vh-panel .vh-row { letter-spacing: -.02em; }
.od-header .vh-pactions { align-items: stretch !important; margin-top: 8px; }
.od-header .vh-pactions .vh-btn { justify-content: center; }

/* Home: each app as a black chapter between the light sections. */
.od-night .od-sub p { max-width: 640px; margin-top: 20px !important; }
.od-night .od-night-title { margin-top: 12px; }
.od-night .od-more a, .od-night .od-more a:visited { color: inherit; }
.od-night .od-night-more { margin-top: 22px; }
/* The invoice window sits on black: a dark title bar, not the light one. */
.od-night .od-browser { margin-top: 72px; background: #2A2A2C; box-shadow: none; }
.od-night .od-browser::before { background: radial-gradient(circle at 5.5px 5.5px, #48484A 5.5px, transparent 6px) 0 0 / 18px 11px repeat-x; }
/* Phones on black need an edge, not a shadow. */
.od-night .od-phone { box-shadow: 0 0 0 1.5px #3A3A3C inset; }
.od-night-mk .od-phones .od-phone { width: 250px !important; }
.od-night-mk .od-phones .od-phone-main { width: 300px !important; }
@media (max-width: 767px) {
  .od-night .od-browser { margin-top: 48px; }
}

/* The three MeloKey phones stay side by side on a phone too, scaled to fit:
   the middle one a little larger, the frame and corners shrunk to match. */
@media (max-width: 767px) {
  .od-phones.od-trio { gap: 10px !important; }
  .od-phones.od-trio .od-phone:not(.od-phone-main) { display: block; width: calc((100% - 20px) * .3) !important; }
  .od-phones.od-trio .od-phone-main { width: calc((100% - 20px) * .4) !important; }
  .od-phones.od-trio .od-phone { padding: 4px; border-radius: 22px; }
  .od .od-phones.od-trio .od-phone img { border-radius: 18px !important; }
}

/* "Sides slide in, middle rises": the outer phones travel in from their own
   sides, the middle one comes up from below a beat later (see odisal.js). */
.od-motion .od-reveal[data-fx="spread"][data-from="left"] { translate: -64px 0; }
.od-motion .od-reveal[data-fx="spread"][data-from="right"] { translate: 64px 0; }
.od-motion .od-reveal[data-fx="spread"][data-from="up"] { translate: 0 64px; }
.od-calm .od-reveal[data-fx="spread"] { translate: 0 0 !important; }

/* Scroll stories switched off for the home page (Tools > Odisal pages). The
   two black app sections then meet, with a hairline between them. */
body.od-no-stories .od-story { display: none !important; }
body.od-no-stories .od-night-mk { border-top: 1px solid #1D1D1F; }

/* ---------- Home page look: Midnight ----------
   Chosen in Tools > Odisal pages. The same home page, every section on black,
   so nothing in Elementor has to change and Bands is one click away. Elementor
   writes each section's colours with its own rules, hence !important. */
/* The palette. Neutral black for the company's pages; each app page swaps in
   a dark version of its own app's colours (Invoicing: ink on paper, without
   the bronze; MeloKey: its navy, with the butter of a chord being played). */
body.od-midnight { --mn-bg: #000; --mn-alt: #111113; --mn-line: #1D1D1F; --mn-text: #A1A1A6;
  --mn-accent: #F5F5F7; --mn-on-accent: #000; background: var(--mn-bg) !important; }
body.od-midnight.od-page-invoicing { --mn-bg: #12110E; --mn-alt: #1B1915; --mn-line: #2A2620; --mn-text: #A9A296;
  --mn-accent: #ECE7DB; --mn-on-accent: #12110E; }
/* Invoicing's other dark shades (Tools > Odisal pages > Page looks), each
   from Invoicing itself: softer greys, or the green and red of two of its
   invoice themes. The accent stays the invoice paper. */
body.od-midnight.od-page-invoicing.od-shade-charcoal { --mn-bg: #22201C; --mn-alt: #2C2924; --mn-line: #3A3630; --mn-text: #B4AEA3; --mn-accent: #F4F1EA; --mn-on-accent: #22201C; }
body.od-midnight.od-page-invoicing.od-shade-graphite { --mn-bg: #1C1C1E; --mn-alt: #2C2C2E; --mn-line: #38383A; --mn-text: #AEAEB2; --mn-accent: #F4F1EA; --mn-on-accent: #1C1C1E; }
body.od-midnight.od-page-invoicing.od-shade-forest { --mn-bg: #0F241D; --mn-alt: #163128; --mn-line: #21403A; --mn-text: #9DB5AA; --mn-accent: #F4F1EA; --mn-on-accent: #0F241D; }
body.od-midnight.od-page-invoicing.od-shade-claret { --mn-bg: #1E0F11; --mn-alt: #2A1619; --mn-line: #3D2226; --mn-text: #BFA4A7; --mn-accent: #F4F1EA; --mn-on-accent: #1E0F11; }
/* Custom shade: the colour set with the sliders in Tools > Odisal pages
   (printed as --sh, --ss and --sl). The rest follows from it with the same
   steps as the fixed shades: panels a little lighter, lines lighter again,
   body text a pale, greyed version of the colour. */
body.od-midnight.od-page-invoicing.od-shade-custom {
  --mn-bg: hsl(var(--sh, 352), var(--ss, 72%), var(--sl, 10%));
  --mn-alt: hsl(var(--sh, 352), var(--ss, 72%), calc(var(--sl, 10%) + 4%));
  --mn-line: hsl(var(--sh, 352), calc(var(--ss, 72%) * .8), calc(var(--sl, 10%) + 9%));
  --mn-text: hsl(var(--sh, 352), calc(var(--ss, 72%) * .42), 73%);
  --mn-accent: #F4F1EA; --mn-on-accent: var(--mn-bg); }
/* Burgundy reds, from darkest to boldest. */
body.od-midnight.od-page-invoicing.od-shade-bordeaux { --mn-bg: #2C070C; --mn-alt: #3A0E15; --mn-line: #4C1820; --mn-text: #CFA3A8; --mn-accent: #F4F1EA; --mn-on-accent: #2C070C; }
body.od-midnight.od-page-invoicing.od-shade-oxblood { --mn-bg: #3A0B10; --mn-alt: #4A1219; --mn-line: #5E1D24; --mn-text: #D8AAAF; --mn-accent: #F4F1EA; --mn-on-accent: #3A0B10; }
body.od-midnight.od-page-invoicing.od-shade-burgundy { --mn-bg: #4A0C16; --mn-alt: #5A131F; --mn-line: #6F1E2A; --mn-text: #E2B0B6; --mn-accent: #F4F1EA; --mn-on-accent: #4A0C16; }
body.od-midnight.od-page-invoicing.od-shade-garnet { --mn-bg: #5A0F1B; --mn-alt: #6B1724; --mn-line: #80222F; --mn-text: #E8B8BD; --mn-accent: #F4F1EA; --mn-on-accent: #5A0F1B; }
body.od-midnight.od-page-invoicing.od-shade-cherry { --mn-bg: #6B1120; --mn-alt: #7D1929; --mn-line: #932533; --mn-text: #EEC0C5; --mn-accent: #F4F1EA; --mn-on-accent: #6B1120; }
body.od-midnight.od-page-melokey { --mn-bg: #0B1020; --mn-alt: #121933; --mn-line: #1F2744; --mn-text: #9AA3C0;
  --mn-accent: #FFD978; --mn-on-accent: #0B1020; }
/* MeloKey's other dark shades (Tools > Odisal pages > Page looks), from its
   icon and keyboard: the navy of its keys, its blue-grey, the dark iOS
   keyboard, or navy with the icon's light blue instead of butter. */
body.od-midnight.od-page-melokey.od-mkshade-keynavy { --mn-bg: #181E33; --mn-alt: #222A45; --mn-line: #2E3756; --mn-text: #A7AFC8; --mn-on-accent: #181E33; }
body.od-midnight.od-page-melokey.od-mkshade-slate { --mn-bg: #171B24; --mn-alt: #212632; --mn-line: #2D3340; --mn-text: #A8AFBE; --mn-on-accent: #171B24; }
body.od-midnight.od-page-melokey.od-mkshade-graphite { --mn-bg: #1C1C1E; --mn-alt: #2C2C2E; --mn-line: #38383A; --mn-text: #AEAEB2; --mn-on-accent: #1C1C1E; }
body.od-midnight.od-page-melokey.od-mkshade-sky { --mn-accent: #BFD4F6; }
body.od-midnight .od-header :is(.elementor-widget-vita_header_menu, .vh) {
  --vh-link: #A1A1A6 !important; --vh-link-hover: #F5F5F7 !important; --vh-link-active: #F5F5F7 !important;
  --vh-border-c: var(--mn-line) !important; --vh-burger-c: #F5F5F7 !important;
  --vh-plink: #F5F5F7 !important; --vh-plink-hover: #A1A1A6 !important; --vh-plink-active: #F5F5F7 !important;
  --vh-pdivider: #2C2C2E !important;
  --vh-fill-text: #000 !important; --vh-fill-bg: #F5F5F7 !important; --vh-fill-border: #F5F5F7 !important;
  --vh-fill-text-h: #000 !important; --vh-fill-bg-h: #FFF !important; --vh-fill-border-h: #FFF !important;
}
body.od-midnight .od-header .vh-bar { background: var(--mn-bg) !important; }
body.od-midnight .od-header .vh-drawer { background: var(--mn-bg) !important; }
body.od-midnight .od-header img.vh-logo-img, body.od-midnight .od-header .vh-plogo img { filter: invert(1); }
body.od-midnight .od-header .vh-ptext { color: #A1A1A6 !important; }

/* Every section after the hero: black, with a hairline between them. */
body.od-midnight .od-tile:not(.od-home-hero) { background: var(--mn-bg) !important; border-top: 1px solid var(--mn-line); }
body.od-midnight .od-tile:not(.od-home-hero) .elementor-heading-title { color: #F5F5F7 !important; }
body.od-midnight .od-tile:not(.od-home-hero) .elementor-widget-text-editor { color: var(--mn-text) !important; }
body.od-midnight .od-tile .od-more a { color: #2997FF; }
body.od-midnight .od-night .elementor-widget-text-editor.od-night-more { color: inherit !important; }
body.od-midnight .od-night-inv .od-night-more { color: #ECE7DB !important; }
body.od-midnight .od-night-mk .od-night-more { color: #FFD978 !important; }
body.od-midnight .od-night-inv .elementor-widget-heading:first-child .elementor-heading-title { color: #ECE7DB !important; }
body.od-midnight .od-night-mk .elementor-widget-heading:first-child .elementor-heading-title { color: #FFD978 !important; }

/* "Our apps": on black the cards lose their tiles; a hairline splits the two. */
body.od-midnight .od-app { background: transparent !important; border-radius: 0 !important; }
body.od-midnight .od-app + .od-app { border-left: 1px solid #2C2C2E; }
body.od-midnight .od-app .od-sub { color: #A1A1A6 !important; }
body.od-midnight .od-app .od-app-status { color: #ECE7DB !important; }
body.od-midnight .od-app + .od-app .od-app-status { color: #FFD978 !important; }
@media (max-width: 767px) {
  body.od-midnight .od-app + .od-app { border-left: 0; border-top: 1px solid #2C2C2E; }
}

/* Stories: frames keep their edges on black; the phone tabs turn dark. */
body.od-midnight .od-story .od-phone { box-shadow: 0 0 0 1.5px #3A3A3C inset; }
body.od-midnight .od-story .od-story-win { box-shadow: 0 0 0 1px #2C2C2E; }
/* Tabs in the page's own palette: the chosen one takes its accent (butter on
   MeloKey, paper on Invoicing, white elsewhere), the rest its second shade. */
body.od-midnight .od-story-tabbar button { background: var(--mn-alt) !important; color: var(--mn-text) !important; }
body.od-midnight .od-story-tabbar button[aria-selected="true"] { background: var(--mn-accent) !important; color: var(--mn-on-accent) !important; }

/* Footer. */
body.od-midnight .od-foot .elementor-widget-text-editor { color: #6E6E73 !important; }
body.od-midnight .od-foot a { color: #A1A1A6; }
body.od-midnight .od-foot-note { border-bottom-color: #2C2C2E; }

/* App and text pages under Midnight. */
/* Sections that sit on the page's second shade. */
body.od-midnight :is(#looks, .od-half) { background: var(--mn-alt) !important; }
body.od-midnight .od-pair { background: var(--mn-bg) !important; }
body.od-midnight :is(.od-pair, .od-subbar) .elementor-heading-title { color: #F5F5F7 !important; }
body.od-midnight .od-pair .elementor-widget-text-editor { color: var(--mn-text) !important; }
body.od-midnight .od-subbar { background: var(--mn-bg) !important; border-bottom: 1px solid var(--mn-line); }
/* Buttons: filled ones take the page's accent, outlined ones its outline. */
body.od-midnight .od .elementor-button { background: var(--mn-accent) !important; color: var(--mn-on-accent) !important; border-color: var(--mn-accent) !important; }
@media (hover: hover) and (pointer: fine) {
  body.od-midnight .od .elementor-button:hover { background: #FFF !important; color: var(--mn-on-accent) !important; border-color: #FFF !important; }
}
/* Outlined buttons keep the page's accent as their outline. */
body.od-midnight .od .od-btn-ghost .elementor-button { background: transparent !important; color: var(--mn-accent) !important; }
@media (hover: hover) and (pointer: fine) {
  body.od-midnight .od .od-btn-ghost .elementor-button:hover { background: var(--mn-accent) !important; color: var(--mn-on-accent) !important; border-color: var(--mn-accent) !important; }
}
body.od-midnight.od-page-melokey .od-tile .od-more a, body.od-midnight.od-page-invoicing .od-tile .od-more a { color: var(--mn-accent); }
/* Privacy and Support: long reading, so the body text is brighter. */
body.od-midnight .od-tile .elementor-widget-text-editor.od-prose { color: #D1D1D6 !important; }
body.od-midnight .od-prose :is(h2, h3) { color: #F5F5F7; }
body.od-midnight .od-prose :is(th, td), body.od-midnight .od-prose tr { border-color: #2C2C2E !important; }
body.od-midnight .od-prose .od-updated, body.od-midnight .od-prose th { color: #8E8E93; }
body.od-midnight .od-prose a { color: #2997FF; }
/* The bar under the header already draws a line; the section after it doesn't draw a second. */
body.od-midnight .od-subbar + .od-tile { border-top: 0; }

/* Bands home page: a black header over the black hero, white once the hero
   has scrolled away (odisal.js sets .od-past-hero). The bar fades its own
   background; the links and the logo fade with it. Open, the menu panel is
   white, so the header keeps its normal colours then. */
.od-header .vh-logo-img { transition: filter 350ms ease; }
:root:not(.od-past-hero) body.od-home:not(.od-midnight) .od-header .vh:not(.is-open) {
  --vh-link: #A1A1A6 !important; --vh-link-hover: #F5F5F7 !important; --vh-link-active: #F5F5F7 !important;
  --vh-border-c: #1D1D1F !important; --vh-burger-c: #F5F5F7 !important;
}
:root:not(.od-past-hero) body.od-home:not(.od-midnight) .od-header .vh:not(.is-open) .vh-bar { background-color: #000 !important; }
:root:not(.od-past-hero) body.od-home:not(.od-midnight) .od-header .vh:not(.is-open) img.vh-logo-img { filter: invert(1); }

/* App pages: the app's icon above its name (the size of the home page's
   cards) and small beside its name in the bar under the header. Corners
   follow the iOS icon shape: about 22% of the width. */
.od-hero-icon { width: 96px !important; margin: 0 auto 20px !important; }
.od .od-hero-icon img { display: block; width: 96px; height: 96px; border-radius: 22px !important; }
.od-subbar-id { width: auto !important; }
.od-subbar-icon { width: 30px !important; flex: none; }
.od .od-subbar-icon img { display: block; width: 30px; height: 30px; border-radius: 7px !important; }
@media (max-width: 767px) {
  .od-hero-icon { width: 76px !important; margin-bottom: 16px !important; }
  .od .od-hero-icon img { width: 76px; height: 76px; border-radius: 17px !important; }
  .od-subbar-icon { width: 26px !important; }
  .od .od-subbar-icon img { width: 26px; height: 26px; border-radius: 6px !important; }
}
/* On a dark page an icon with a dark tile needs an edge to hold its shape. */
body.od-midnight :is(.od-hero-icon, .od-subbar-icon) img { box-shadow: 0 0 0 1px rgba(255, 255, 255, .12); }

/* The MeloKey launch list form, at the end of the MeloKey page. */
.od-wait { max-width: 520px; margin: 30px auto 0; text-align: left; }
.od-wait-label { display: block; font-size: 15px; font-weight: 500; color: #1D1D1F; margin: 0 0 8px 18px; }
.od-wait-row { display: flex; gap: 10px; }
.od-wait input[type="email"] { flex: 1; min-width: 0; height: 52px; padding: 0 20px; border-radius: 980px; border: 1px solid #D2D2D7; background: #fff;
  font: 400 17px/1.2 var(--od-sans, -apple-system, BlinkMacSystemFont, sans-serif); color: #1D1D1F; -webkit-appearance: none; appearance: none; }
.od-wait input[type="email"]:focus { outline: 2px solid var(--od-link, #0066CC); outline-offset: 2px; border-color: transparent; }
.od-wait button { flex: none; height: 52px; padding: 0 24px; border: 0; border-radius: 980px; background: #1F2640; color: #fff; cursor: pointer;
  font: 500 17px/1 var(--od-sans, -apple-system, BlinkMacSystemFont, sans-serif); touch-action: manipulation; transition: scale 160ms var(--od-ease-out, ease-out), opacity 200ms ease; }
.od-wait button:active { scale: .97; }
.od-wait button:disabled { opacity: .6; }
.od-wait button:focus-visible { outline: 2px solid var(--od-link, #0066CC); outline-offset: 3px; }
.od-wait-note { font-size: 14px; color: #6E6E73; margin: 12px 0 0 18px !important; }
.od-wait-note a { color: inherit; }
.od-wait-trap { position: absolute !important; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.od-wait-done .od-wait-row, .od-wait-done .od-wait-label { display: none; }
.od-wait-done .od-wait-note { font-size: 17px; color: #1D1D1F; text-align: center; margin: 0 !important; }
.od-wait-error .od-wait-note { color: #B3261E; }
@media (max-width: 560px) { .od-wait-row { flex-direction: column; } .od-wait input[type="email"] { flex: none; width: 100%; } .od-wait button { width: 100%; } }
body.od-midnight .od-wait-label, body.od-midnight .od-wait-done .od-wait-note { color: #F5F5F7; }
body.od-midnight .od-wait input[type="email"] { background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.16); color: #F5F5F7; }
body.od-midnight .od-wait button { background: var(--mn-accent, #FFD978); color: var(--mn-on-accent, #0B1020); }

/* MeloKey on iPad: the same drawn frame as the phones, wider and with a
   thinner bezel, as on a real iPad. */
.od-ipad { width: min(560px, 84vw) !important; max-width: 100%; margin: 44px auto 0; flex: none; border-radius: 34px; background: #111; padding: 12px;
  box-shadow: 0 0 0 1.5px #3a3a3c inset, 0 40px 80px -30px rgba(31, 38, 64, .55); }
.od .od-ipad img { display: block; width: 100%; height: auto; border-radius: 22px !important; }
@media (max-width: 767px) { .od-ipad { border-radius: 24px; padding: 8px; margin-top: 32px; } .od .od-ipad img { border-radius: 16px !important; } }

/* MeloKey on phones and tablets: the swipeable phones are the first picture.
   The still phone in the opening section would only repeat them, so it goes.
   (Desktop keeps its three phones: the story there pins instead.) */
@media (max-width: 1024px) {
  .od-story-tabs .od-mk .od-phones { display: none !important; }
  .od-story-tabs .od-mk { padding-bottom: 8px !important; }
}
