/* ═══════════════════════════════════════════════════════════════════════════
   Vanquel landing (public/phone.html, vanquel.com; once Khio Phone)
   ---------------------------------------------------------------------------
   A white page in navy ink. The hero is a very large Libron headline fading
   navy to grey, six pieces of salon conversations scattered round it (Keiki's
   collage, 2026-11-09), and under the buttons three phones standing in a
   band of sky (Blooio's trio, 2026-11-10). Below it the page follows
   onkeiki.com's flow (2026-11-10): channel tabs, then centred headings over
   explore cards, each a product mock with a short caption. Geist text, Geist
   Mono labels, soft-shadowed cards and the blue of the V as the one accent.
   The sky is a steel-blue gradient everywhere it appears (hero band, channel
   tabs, closing form, the V of the footer wordmark); phone-landing.ts halftones
   one cloud photograph (/images/phone/clouds.webp) over it into each
   canvas.kp-clouds, and the gradient alone is the complete look without
   script, WebGL or the photo. Phones (.ph) and every message piece are
   code, not images, so they stay sharp at any size. (AI-made images were
   tried on 2026-11-06 and looked soft; clouds grown from noise were tried
   on 2026-11-10 and looked airbrushed next to a real sky.)
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Tokens and base ──────────────────────────────────────────────────── */
:root {
    --bg: #ffffff;
    --panel: #ffffff;
    --panel-2: #f3f5fa;
    --line: rgba(20, 38, 83, .08);
    --line-2: rgba(20, 38, 83, .15);
    --text: #0f1e3f;
    --muted: #5a6684;
    --dim: #8e97ae;
    --ink: linear-gradient(180deg, #0f1e3f 35%, rgba(20, 38, 83, .58));
    --card-shadow: 0 1px 2px rgba(20, 38, 83, .05), 0 14px 44px rgba(20, 38, 83, .08);
    /* Ink and blue are sampled from the Vanquel logo. Message bubbles keep
       iMessage's own blue, so a thread still looks like Messages. */
    --blue: #0071fc;
    --imsg: #0a84ff;
    --blue-soft: #5aa9ff;
    /* The sky behind every cloud canvas, and the whole look where clouds
       cannot be drawn: steel blue, lighter toward the horizon, with two
       soft banks of white low down. */
    --blue-panel: radial-gradient(ellipse 60% 55% at 86% 108%, rgba(255, 255, 255, .4), transparent 65%), radial-gradient(ellipse 45% 40% at 8% 112%, rgba(255, 255, 255, .22), transparent 70%), linear-gradient(180deg, #2a5a8a 0%, #4f86b6 70%, #6298c7 100%);
    --sans: 'Geist', 'Geist Fallback', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --mono: 'Geist Mono', ui-monospace, Menlo, monospace;
    /* Headlines: Libron, James's own headline face (Arrow site, khio-page). */
    --display: 'Libron', Georgia, 'Times New Roman', serif;
    --ios: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Geist', sans-serif;
}
@font-face { font-family: 'Libron'; src: url(/fonts/Libron-Regular.woff2) format('woff2'); font-weight: 400; font-style: normal; font-display: block; }
/* Segoe UI widened to Geist's measure, so text on Windows does not shuffle
   sideways when Geist arrives. Elsewhere this face finds nothing and is skipped. */
@font-face { font-family: 'Geist Fallback'; src: local('Segoe UI'); font-weight: 300 400; size-adjust: 104%; }
@font-face { font-family: 'Geist Fallback'; src: local('Segoe UI Semibold'); font-weight: 500 700; size-adjust: 105%; }
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 96px; }
body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font: 400 16px/1.55 var(--sans);
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}
a { color: inherit; }
h1, h2, h3, p { margin: 0; }
h1, h2, h3 { text-wrap: balance; }
h2 {
    font: 400 clamp(34px, 4.6vw, 58px)/1.06 var(--display); letter-spacing: -0.02em;
    background: var(--ink); -webkit-background-clip: text; background-clip: text; color: transparent;
    /* Room below the tight line height for descenders, as on the h1. */
    padding-bottom: .12em; margin-bottom: -.12em;
}
h3 { font-size: 17px; font-weight: 600; letter-spacing: -0.01em; }
/* An icon is its ligature name ("chevron_left") until the icon font arrives.
   The box is held at one em and clipped so that name can never show or
   push its neighbours about; the font itself is loaded with display=block. */
.material-symbols-outlined { display: inline-block; flex: none; width: 1em; height: 1em; overflow: hidden; font-size: 20px; line-height: 1; font-variation-settings: 'wght' 300; }
.kp-mono-label { font: 500 12px/1.2 var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }

/* ── Buttons and links ────────────────────────────────────────────────── */
.kp-pill {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 9px 16px; border-radius: 10px; border: 0; cursor: pointer;
    font: 500 14px/1.2 var(--sans); text-decoration: none; white-space: nowrap;
    transition: transform .15s ease, background .15s ease, box-shadow .15s ease;
}
.kp-pill:hover { transform: translateY(-1px); }
.kp-pill:active { transform: scale(.97); }
.kp-pill:disabled { opacity: .6; cursor: default; transform: none; }
.kp-pill-lg { padding: 13px 22px; font-size: 15px; }
.kp-pill-blue { background: var(--blue); color: #fff; }
.kp-pill-blue:hover { background: #005fd6; }
.kp-text-link { display: inline-flex; gap: 6px; font-weight: 500; text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px; }
.kp-text-link span { text-decoration: none; transition: transform .15s ease; }
.kp-text-link:hover span { transform: translateX(3px); }

/* ── Logo ─────────────────────────────────────────────────────────────── */
/* The Vanquel wordmark, blue V and navy name (/images/vanquel/). */
.kp-logo { display: inline-flex; align-items: center; }
.kp-logo img { display: block; width: auto; height: 28px; }

/* ── Floating nav ─────────────────────────────────────────────────────── */
.kp-nav {
    position: fixed; z-index: 50; top: 14px; left: 50%; transform: translateX(-50%);
    width: min(1120px, calc(100% - 32px));
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
    padding: 9px 9px 9px 18px; border-radius: 16px;
    background: rgba(255, 255, 255, .78); border: 1px solid var(--line-2); box-shadow: 0 6px 24px rgba(20, 38, 83, .08);
    backdrop-filter: blur(18px) saturate(1.4); -webkit-backdrop-filter: blur(18px) saturate(1.4);
}
.kp-links { display: flex; gap: 26px; }
.kp-links a { text-decoration: none; font-size: 14px; color: var(--muted); }
.kp-links a:hover { color: var(--text); }
.kp-nav-ctas { display: flex; gap: 8px; }
.kp-icon-btn {
    display: grid; place-items: center; width: 36px; height: 36px; border-radius: 10px;
    background: var(--panel-2); border: 1px solid var(--line-2); color: var(--text); text-decoration: none;
}

/* ── Hero ─────────────────────────────────────────────────────────────── */
/* White like the rest of the page: the headline in navy ink with message
   pieces scattered round it, then three phones standing in a band of sky. */
.kp-hero {
    position: relative; overflow: hidden;
    display: flex; flex-direction: column; align-items: center;
    padding: 150px 16px 0;
}
.kp-hero-copy { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; text-align: center; }
.kp-hero h1 {
    font: 400 clamp(44px, 5.8vw, 100px)/0.98 var(--display); letter-spacing: -0.03em;
    background: var(--ink); -webkit-background-clip: text; background-clip: text; color: transparent;
    /* The gradient is clipped to the text box, so give descenders (the g) room
       below the tight line height without moving anything under it. */
    padding: 0 .04em .14em; margin-bottom: -.14em;
}
.kp-chips {
    list-style: none; padding: 0; margin: 30px 0 0; max-width: 760px;
    display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 18px;
    color: var(--text); font-size: 15px; font-weight: 500;
}
.kp-chips li { display: inline-flex; align-items: center; gap: 8px; }
.kp-chip-ico { display: grid; place-items: center; width: 22px; height: 22px; border-radius: 6px; background: var(--panel-2); border: 1px solid var(--line-2); color: var(--text); }
.kp-chip-ico .material-symbols-outlined { font-size: 15px; font-variation-settings: 'FILL' 1, 'wght' 500; }
.kp-chip-blue { background: #34c759; border-color: #34c759; color: #fff; }
.kp-plus { font-size: 18px; font-weight: 300; }
.kp-hero-ctas { display: flex; align-items: center; gap: 24px; margin-top: 34px; color: var(--text); }

/* The phones stand in a rounded band of sky and rise out of its top edge;
   the stage clips them at the band's foot. --tx and --ty (set by
   phone-landing.ts, each -0.5 to 0.5) lean the three with the pointer, the
   side phones more than the middle one, so they read as nearer. */
.kp-phones {
    --tx: 0; --ty: 0;
    position: relative; z-index: 1; width: min(1400px, 100%); height: 780px; margin-top: 30px; padding-top: 30px;
    display: flex; justify-content: center; align-items: flex-start; gap: 72px;
    overflow: hidden; border-radius: 0 0 32px 32px; perspective: 1600px;
}
.kp-band { position: absolute; inset: 130px 0 0; isolation: isolate; overflow: hidden; border-radius: 32px; background: var(--blue-panel); }
.kp-phones .ph { flex: none; transition: transform .6s cubic-bezier(.2, .7, .2, 1); }
.ph-center { --w: 400px; z-index: 2; transform: translate3d(calc(var(--tx) * -10px), calc(var(--ty) * -6px), 0); }
.ph-side { --w: 300px; margin-top: 180px; }
.ph-left { transform-origin: 100% 40%; transform: translate3d(calc(var(--tx) * -24px), calc(var(--ty) * -12px), 0) rotateY(calc(20deg + var(--tx) * 5deg)) rotateZ(-1.5deg); }
.ph-right { transform-origin: 0 40%; transform: translate3d(calc(var(--tx) * -24px), calc(var(--ty) * -12px), 0) rotateY(calc(-20deg + var(--tx) * 5deg)) rotateZ(1.5deg); }

/* Halftone sky. The canvas sits over its host's gradient and fades in once
   phone-landing.ts has the cloud photo and has drawn a frame; until then,
   and without it, the gradient is the sky. */
.kp-clouds { position: absolute; inset: 0; z-index: -1; width: 100%; height: 100%; pointer-events: none; opacity: 0; transition: opacity .9s ease; }
.kp-clouds.is-on { opacity: 1; }

/* Six message pieces scattered round the headline, three down each side.
   They sit under the text, bob gently, and only show where there is room.
   --tx and --ty (set by phone-landing.ts from the pointer over the hero,
   each -0.5 to 0.5) drift every piece a few pixels the other way, each by
   its own amount, so they sit at different depths. */
.kp-frags { --tx: 0; --ty: 0; position: absolute; inset: 0; z-index: 0; pointer-events: none; font: 10px/1.4 var(--ios); text-align: left; }
.kp-frag { position: absolute; width: 236px; display: flex; flex-direction: column; gap: 6px; transition: transform .8s cubic-bezier(.2, .7, .2, 1); animation: kp-in-pop .5s cubic-bezier(.2, .7, .2, 1) backwards, kp-float 7s ease-in-out infinite; }
.kp-frag .b { max-width: 90%; box-shadow: 0 8px 24px rgba(20, 38, 83, .14); }
.kp-frag-card { padding: 12px 14px; border-radius: 16px; background: #fff; color: #000; border: 1px solid var(--line); box-shadow: 0 1px 2px rgba(20, 38, 83, .06), 0 18px 44px rgba(20, 38, 83, .14); }
.kp-frag-head { display: flex; align-items: center; gap: 10px; }
.kp-frag-head > span:nth-child(2) { display: flex; flex-direction: column; }
.kp-frag-when { margin-top: 10px; font-size: 12px; font-weight: 600; }
.kp-frag-action { margin-top: 10px; padding: 7px 0; border-radius: 9px; border: 1px solid #d7dbe4; color: var(--blue); text-align: center; font-size: 11px; font-weight: 600; }
.kp-frag-aphead { margin-bottom: 6px; font: 700 11px/1 var(--ios); }
.kp-frag-card .ph-card-big { margin: 0 0 2px; }
.kp-frag-card .ph-pay-btn { margin-top: 10px; }
/* Out at the screen edges, bleeding a little past them on laptops. */
.kp-frag-tl { top: 110px; left: max(-36px, calc(50% - 800px)); transform: translate3d(calc(var(--tx) * -18px), calc(var(--ty) * -12px), 0) rotate(-3deg); animation-delay: .22s, 0s; }
.kp-frag-tr { top: 96px; right: max(-36px, calc(50% - 800px)); transform: translate3d(calc(var(--tx) * -26px), calc(var(--ty) * -16px), 0) rotate(2.5deg); animation-delay: .28s, -2s; }
.kp-frag-ml { top: 370px; left: max(-24px, calc(50% - 780px)); transform: translate3d(calc(var(--tx) * -12px), calc(var(--ty) * -8px), 0) rotate(2deg); animation-delay: .34s, -4s; }
.kp-frag-mr { top: 356px; right: max(-24px, calc(50% - 780px)); transform: translate3d(calc(var(--tx) * -20px), calc(var(--ty) * -12px), 0) rotate(-2deg); animation-delay: .4s, -5s; }
@keyframes kp-float { 0%, 100% { translate: 0 0; } 50% { translate: 0 -8px; } }
@media (max-width: 1199px) { .kp-frags { display: none; } }

/* Load-in: the headline, the chips, the buttons, the six pieces, then the
   phones rising into the sky, about nine tenths of a second end to end.
   Plain CSS keyframes that only describe where each thing comes FROM, so
   they need no script and nothing can be left hidden. They move with
   translate and scale, which leaves every transform above alone. */
@keyframes kp-in { from { opacity: 0; translate: 0 18px; } }
@keyframes kp-in-pop { from { opacity: 0; scale: .92; } }
@keyframes kp-in-rise { from { opacity: 0; translate: 0 56px; } }
@keyframes kp-in-fade { from { opacity: 0; } }
.kp-hero h1, .kp-chips, .kp-hero-ctas { animation: kp-in .6s cubic-bezier(.2, .7, .2, 1) backwards; }
.kp-chips { animation-delay: .08s; }
.kp-hero-ctas { animation-delay: .16s; }
.kp-nav, .kp-band { animation: kp-in-fade .6s ease backwards; }
.kp-band { animation-delay: .15s; }
.kp-phones .ph { animation: kp-in-rise .65s cubic-bezier(.2, .7, .2, 1) .18s backwards; }
.kp-phones .ph-side { animation-delay: .26s; }
/* Laptops: slimmer cards, slightly smaller phones. */
@media (min-width: 1200px) and (max-width: 1439px) {
    .kp-phones { height: 700px; gap: 52px; }
    .ph-center { --w: 360px; }
    .ph-side { --w: 270px; margin-top: 150px; }
    .kp-frag { width: 206px; }
}
/* Short laptop screens: start the headline higher so the buttons sit well above the fold. */
@media (min-width: 1024px) and (max-height: 820px) {
    .kp-hero { padding-top: 122px; }
}

/* ── iPhone mockup ────────────────────────────────────────────────────── */
/* Everything inside a phone is sized in em, and one em is 1/28 of the
   phone's width (--w), so a phone of any size keeps true proportions: set
   --w and nothing else. Outside in: a brushed-titanium band with lit edges,
   the black glass border, then the screen. The pseudo-elements are the
   side buttons. .ph-dark flips the screen to dark mode through the --ph-*
   colours. Bubbles and cards also appear on their own in the hero, so each
   colour carries its light-mode value as a fallback. */
.ph {
    --ph-bg: #fff; --ph-fg: #000; --ph-them: #e9e9eb; --ph-sub: #8e8e93; --ph-chip: #f2f2f7;
    --ph-card: #fff; --ph-card-line: #e3e3e7; --ph-field: #d8d8dc; --ph-slot: #b9d4f5;
    position: relative; flex: none; width: var(--w, 280px); aspect-ratio: 9 / 19.5; padding: .36em;
    font: calc(var(--w, 280px) / 28)/1.3 var(--ios); text-align: left;
    border-radius: 4.7em;
    background: linear-gradient(100deg, #f4f2ee 0%, #a19d96 4%, #d9d6d0 11%, #c2beb7 48%, #dcd9d3 88%, #8d8982 96%, #efede9 100%);
    box-shadow: inset 0 0 0 .07em rgba(255, 255, 255, .6), inset 0 0 .28em .1em rgba(60, 56, 50, .55),
        0 3.4em 6em rgba(8, 28, 64, .34), 0 .8em 1.8em rgba(8, 28, 64, .2);
}
.ph::before, .ph::after { content: ''; position: absolute; width: .3em; border-radius: .2em; background: linear-gradient(90deg, #8d8982, #d6d3cd 60%, #a19d96); }
.ph::before { left: -.2em; top: 17%; height: 22%; -webkit-mask: linear-gradient(#000 0 20%, transparent 20% 33%, #000 33% 62%, transparent 62% 71%, #000 71%); mask: linear-gradient(#000 0 20%, transparent 20% 33%, #000 33% 62%, transparent 62% 71%, #000 71%); }
.ph::after { right: -.2em; top: 27%; height: 13%; }
.ph-dark {
    --ph-bg: #000; --ph-fg: #fff; --ph-them: #262629; --ph-sub: #98989f; --ph-chip: #1c1c1e;
    --ph-card: #1c1c1e; --ph-card-line: #2c2c2e; --ph-field: #3a3a3c; --ph-slot: #1f4f8a;
}
.ph-screen {
    position: relative; height: 100%; overflow: hidden; display: flex; flex-direction: column;
    border: .5em solid #000; border-radius: 4.35em; background: var(--ph-bg); color: var(--ph-fg);
}
/* Home indicator */
.ph-screen::after { content: ''; position: absolute; left: 50%; bottom: .55em; width: 9.6em; height: .36em; margin-left: -4.8em; border-radius: .36em; background: var(--ph-fg); }
.ph-island { position: absolute; top: .95em; left: 50%; z-index: 2; width: 8.6em; height: 2.5em; margin-left: -4.3em; border-radius: 1.3em; background: #000; }
.ph-island::after { content: ''; position: absolute; right: .75em; top: .8em; width: .9em; height: .9em; border-radius: 50%; background: radial-gradient(circle at 35% 35%, #2a3350, #0b0d16 60%); }
.ph-status { display: flex; justify-content: space-between; align-items: center; padding: 1.5em 2.3em 0 3.1em; }
.ph-status > span:first-child { font-size: 1.32em; font-weight: 600; letter-spacing: -.01em; }
.ph-sys { display: inline-flex; align-items: center; gap: .4em; }
.ph-sys .material-symbols-outlined { font-size: 1.5em; font-variation-settings: 'FILL' 1, 'wght' 600; }
.ph-batt { position: relative; width: 2.3em; height: 1.1em; border-radius: .34em; border: .1em solid color-mix(in srgb, currentColor 45%, transparent); }
.ph-batt::before { content: ''; position: absolute; inset: .1em; border-radius: .16em; background: currentColor; }
.ph-batt::after { content: ''; position: absolute; right: -.3em; top: .28em; width: .14em; height: .36em; border-radius: 0 .1em .1em 0; background: color-mix(in srgb, currentColor 45%, transparent); }
/* The Messages header: back button, the sender's picture, its name pill and
   the day stamp. Businesses get a rounded tile, a group chat a circle. */
.ph-head { position: relative; display: flex; flex-direction: column; align-items: center; gap: .5em; padding: 1.5em 0 .7em; }
.ph-back { position: absolute; left: .55em; top: .7em; display: grid; place-items: center; width: 1.5em; height: 1.5em; border-radius: 50%; background: var(--ph-chip); color: var(--ph-fg); font-size: 2.1em; }
.ph-av { display: grid; place-items: center; flex: none; width: 2.7em; height: 2.7em; border-radius: .68em; font: 600 1.7em/1 var(--sans); color: #fff; box-shadow: 0 .05em .25em rgba(0, 0, 0, .18); }
.ph-av-ink { background: linear-gradient(135deg, #2b2b30, #0e0e10); }
.ph-dark .ph-av-ink { background: linear-gradient(135deg, #fff, #dcdce0); color: #111; }
.ph-av-teal { background: linear-gradient(135deg, #2bb3a3, #137a8a); }
.ph-av-amber { background: linear-gradient(135deg, #f4b35a, #c46a1f); }
.ph-av-rose { background: linear-gradient(135deg, #f08a8a, #b4405c); }
.ph-name { display: inline-flex; align-items: center; gap: .15em; padding: .32em .5em .32em .8em; border-radius: 1.2em; background: var(--ph-chip); font-size: 1.12em; font-weight: 600; letter-spacing: -.01em; }
.ph-name:not(:has(.material-symbols-outlined)) { padding-right: .8em; }
.ph-name .material-symbols-outlined { font-size: 1.15em; color: var(--ph-sub); }
.ph-when { font-size: .95em; color: var(--ph-sub); }
.ph-thread { flex: 1; isolation: isolate; display: flex; flex-direction: column; gap: .55em; padding: .5em 1.5em; overflow: hidden; }
/* Bubbles. The last one in a run from the same side grows a tail: a curl
   in the bubble's colour, trimmed by a second curl in the screen's colour. */
.b {
    position: relative; max-width: 78%; padding: .5em .88em .54em; border-radius: 1.38em;
    font-size: 1.27em; line-height: 1.26; letter-spacing: -.012em;
}
.b.me { align-self: flex-end; background: var(--imsg); color: #fff; }
.b.them { align-self: flex-start; background: var(--ph-them, #e9e9eb); color: var(--ph-fg, #000); }
.b.me + .b.me, .b.them + .b.them { margin-top: -.3em; }
.ph .b.me:not(:has(+ .b.me))::before, .ph .b.them:not(:has(+ .b.them))::before { content: ''; position: absolute; z-index: -1; bottom: 0; width: 1.5em; height: 1.2em; background: inherit; }
.ph .b.me:not(:has(+ .b.me))::before { right: -.52em; border-bottom-left-radius: 1.1em 1em; }
.ph .b.them:not(:has(+ .b.them))::before { left: -.52em; border-bottom-right-radius: 1.1em 1em; }
.ph .b.me:not(:has(+ .b.me))::after, .ph .b.them:not(:has(+ .b.them))::after { content: ''; position: absolute; z-index: -1; bottom: 0; width: .8em; height: 1.2em; background: var(--ph-bg); }
.ph .b.me:not(:has(+ .b.me))::after { right: -.8em; border-bottom-left-radius: .7em; }
.ph .b.them:not(:has(+ .b.them))::after { left: -.8em; border-bottom-right-radius: .7em; }
.has-tap { margin-top: .9em; }
.ph-tap {
    position: absolute; top: -1.15em; left: -.9em; display: grid; place-items: center; width: 2.1em; height: 2.1em;
    border-radius: 50%; background: var(--ph-them, #e9e9eb); border: .16em solid var(--ph-bg, #fff); font-size: .88em;
}
.ph-read { align-self: flex-end; margin: -.2em .3em 0; font-size: .95em; font-weight: 500; color: var(--ph-sub); }
.ph-typing { display: inline-flex; gap: .3em; padding: .85em .95em; }
.ph-typing i { width: .5em; height: .5em; border-radius: 50%; background: #8e8e93; animation: kp-type 1.2s infinite ease-in-out; }
.ph-typing i:nth-child(2) { animation-delay: .15s; }
.ph-typing i:nth-child(3) { animation-delay: .3s; }
@keyframes kp-type { 0%, 60%, 100% { opacity: .35; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-.16em); } }
/* A typing bubble that stands in for the reply under it while a thread
   plays (see "Mocks that play"). It takes no room in the thread, and it is
   invisible except during its own moment of the sequence. */
.ph-wait { position: relative; height: 0; margin-bottom: -.55em; }
.ph-wait::before {
    content: ''; position: absolute; left: 0; top: 0; width: 5.1em; height: 2.8em; border-radius: 1.4em; opacity: 0; transform-origin: 0 100%;
    background: radial-gradient(circle at 1.53em 50%, #8e8e93 .3em, transparent .34em), radial-gradient(circle at 2.55em 50%, #8e8e93 .3em, transparent .34em), radial-gradient(circle at 3.57em 50%, #8e8e93 .3em, transparent .34em), var(--ph-them);
}
/* The composer: a round plus button and the iMessage field with its mic. */
.ph-input { display: flex; align-items: center; gap: .7em; padding: .7em 1.2em 2em; color: var(--ph-sub); }
.ph-input > .material-symbols-outlined { display: grid; place-items: center; flex: none; width: 1.55em; height: 1.55em; border-radius: 50%; background: var(--ph-chip); font-size: 2em; }
.ph-field { flex: 1; display: flex; justify-content: space-between; align-items: center; padding: .42em .7em .42em 1em; border-radius: 1.5em; border: .08em solid var(--ph-field); font-size: 1.27em; }
.ph-field::after { content: 'mic'; flex: none; width: 1em; height: 1em; overflow: hidden; font: 1.25em/1 'Material Symbols Outlined'; font-variation-settings: 'FILL' 1; }

/* Cards inside the thread */
.ph-card {
    display: flex; align-items: center; gap: 1em; max-width: 88%; padding: 1em 1.2em;
    border-radius: 1.6em; background: var(--ph-card, #fff); border: .1em solid var(--ph-card-line, #e3e3e7); box-shadow: 0 .2em 1em rgba(0, 0, 0, .05);
}
.ph-card-ico { display: grid; place-items: center; flex: none; width: 1.7em; height: 1.7em; border-radius: .5em; background: color-mix(in srgb, var(--blue) 12%, transparent); color: var(--blue); font-size: 1.8em; }
.ph-card-title { font-size: 1.25em; font-weight: 600; letter-spacing: -.01em; white-space: nowrap; }
.ph-card-sub { font-size: 1.05em; color: var(--ph-sub, #8e8e93); }
.ph-card-big { margin: .08em 0 .34em; font-size: 2.4em; font-weight: 600; letter-spacing: -.02em; }
.ph-ok { margin-left: auto; color: #34c759; font-size: 2em; font-variation-settings: 'FILL' 1; }
.ph-day { display: flex; justify-content: space-between; align-items: baseline; margin: .9em 0 .5em; font-size: 1.05em; font-weight: 600; }
.ph-day span { font-weight: 400; color: var(--blue); }
.ph-times { display: flex; gap: .5em; }
.ph-times span { flex: 1; text-align: center; padding: .5em 0; border-radius: .8em; border: .1em solid var(--ph-slot, #b9d4f5); color: var(--blue); }
.ph-times span.on { background: var(--blue); border-color: var(--blue); color: #fff; }
.ph-card-block { display: block; min-width: 70%; }
.ph-pay-btn { display: block; text-align: center; padding: .65em; border-radius: .8em; background: var(--ph-fg, #000); color: var(--ph-bg, #fff); font-size: 1.2em; font-weight: 600; }
/* A full-screen picker, as when a time-slot card is opened. */
.ph-sheet { flex: 1; margin: 1.6em .9em 0; padding: 1.8em 1.5em; border-radius: 2.2em 2.2em 0 0; background: var(--ph-card); }
.ph-sheet-title { margin-bottom: .3em; font-size: 1.6em; font-weight: 600; line-height: 1.2; letter-spacing: -.015em; }
.ph-sheet .ph-day { margin-top: 1.5em; font-size: 1.25em; }
.ph-sheet .ph-times { margin-bottom: .7em; }
.ph-sheet .ph-times span { padding: .7em 0; font-size: 1.05em; }
/* The channels that are not iMessage: green bubbles for SMS, and a
   tinted wallpaper with pale green replies for WhatsApp. */
.ph-sms { --imsg: #34c759; }
.ph-wa { --ph-bg: #efeae2; --ph-them: #fff; --ph-chip: #fff; --imsg: #d9fdd3; }
.ph-wa .b.me { color: #111; }

/* ── Sections ─────────────────────────────────────────────────────────── */
/* Every section opens the same way: a large centred heading, one or two
   sentences under it, then its mocks. */
main { display: block; }
.kp-section { max-width: 1180px; margin: 0 auto; padding: clamp(88px, 12vw, 160px) 24px 0; }
.kp-center { text-align: center; display: flex; flex-direction: column; align-items: center; }
.kp-lede { max-width: 620px; margin: 18px auto 0; color: var(--muted); font-size: 17px; text-wrap: pretty; }
/* Status tags, in the work log and the inbox. */
mark { flex: none; padding: 1px 6px; border-radius: 5px; background: rgba(10, 132, 255, .1); color: #0a6fd6; font-size: 13px; font-weight: 500; white-space: nowrap; }
mark.green { background: rgba(22, 163, 74, .1); color: #15803d; }
mark.amber { background: rgba(217, 119, 6, .12); color: #b45309; }

/* Channel tabs: one panel of sky, a tab per channel. Only iMessage is live;
   the others carry a "Coming soon" tag on the tab itself. */
.kp-tabs { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 36px; }
.kp-tabs button {
    display: inline-flex; align-items: center; gap: 8px; padding: 10px 14px; border-radius: 10px; cursor: pointer;
    background: transparent; border: 1px solid transparent; color: var(--dim); font: 500 14px/1 var(--sans);
    transition: background .25s ease, border-color .25s ease, color .25s ease;
}
.kp-tabs button:hover { color: var(--text); }
.kp-tabs button[aria-selected="true"] { background: var(--panel-2); border-color: var(--line-2); color: var(--text); }
.kp-tabs em { padding: 3px 6px; border-radius: 5px; background: var(--panel-2); color: var(--muted); font: 500 10px/1 var(--mono); letter-spacing: .04em; text-transform: uppercase; }
.kp-tabs button[aria-selected="true"] em { background: #fff; }
.kp-tabs em.kp-live { background: rgba(22, 163, 74, .12); color: #15803d; }
.kp-tab-stage {
    position: relative; isolation: isolate; overflow: hidden; width: 100%; margin-top: 18px; border-radius: 24px; min-height: 520px;
    background: var(--blue-panel); text-align: left;
}
.kp-panel { display: grid; grid-template-columns: 1fr 1fr; align-items: end; gap: 32px; padding: 48px 56px 0; min-height: 520px; }
.kp-panel[hidden] { display: none; }
/* A panel is not drawn while hidden, so these run afresh each time a tab
   shows it: the copy fades up and the phone (or the email) rises. */
.kp-panel-copy { animation: kp-in .5s cubic-bezier(.2, .7, .2, 1) backwards; }
.kp-panel > .ph, .kp-mail { animation: kp-in-rise .6s cubic-bezier(.2, .7, .2, 1) .05s backwards; }
.kp-panel-copy { align-self: start; padding: 16px 0 48px; color: #fff; text-shadow: 0 1px 12px rgba(20, 60, 120, .35); }
.kp-panel-copy .kp-mono-label { color: rgba(255, 255, 255, .8); }
.kp-panel-copy h3 { margin-top: 14px; font: 400 clamp(30px, 3.6vw, 44px)/1.08 var(--display); letter-spacing: -0.02em; }
.kp-panel-copy > p:not([class]) { margin-top: 16px; max-width: 420px; color: rgba(255, 255, 255, .88); }
/* The brief: the few plain sentences a salon gives its agent. */
.kp-brief-label { margin-top: 28px; font: 500 11px/1 var(--mono); letter-spacing: .08em; text-transform: uppercase; color: rgba(255, 255, 255, .7); }
.kp-brief { list-style: none; max-width: 420px; margin: 12px 0 0; padding: 0; display: grid; gap: 10px; font-size: 15.5px; line-height: 1.45; }
.kp-brief li { padding-left: 16px; border-left: 2px solid rgba(255, 255, 255, .35); color: rgba(255, 255, 255, .82); }
.kp-brief li:first-child { border-color: #fff; color: #fff; }
.ph-panel { --w: 280px; justify-self: center; aspect-ratio: auto; height: 472px; padding-bottom: 0; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.ph-panel .ph-screen { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
/* An email, for the channel that is not a phone thread. */
.kp-mail { justify-self: center; align-self: center; width: min(400px, 100%); margin-bottom: 48px; padding: 22px 24px; border-radius: 18px; background: #fff; color: var(--text); font-size: 14.5px; box-shadow: 0 24px 60px rgba(0, 25, 90, .25); }
.kp-mail p + p { margin-top: 10px; }
.kp-mail-sub { font-size: 17px; font-weight: 600; letter-spacing: -.01em; }
.kp-mail-from { padding-bottom: 12px; border-bottom: 1px solid var(--line); color: var(--muted); font-size: 13px; }
.kp-mail-from b { color: var(--text); font-weight: 600; }
.kp-mail-file { display: inline-flex; align-items: center; gap: 8px; padding: 8px 12px; border-radius: 10px; background: var(--panel-2); border: 1px solid var(--line); font-size: 13px; font-weight: 500; }
.kp-mail-file .material-symbols-outlined { color: #dc2626; }

/* Explore cards: a product mock on a pale wash, a short caption under it.
   Two to a row; .kp-x-wide takes the whole row. */
.kp-xgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; width: 100%; margin-top: 56px; text-align: left; }
.kp-x { display: flex; flex-direction: column; min-width: 0; overflow: hidden; border-radius: 24px; background: var(--panel); border: 1px solid var(--line); box-shadow: var(--card-shadow); }
.kp-x-wide { grid-column: 1 / -1; }
/* With a mouse, a card lifts a little under the pointer. It moves with
   translate, which the scroll reveal's transform leaves alone. */
@media (hover: hover) {
    .kp-x { transition: translate .35s cubic-bezier(.2, .7, .2, 1), box-shadow .35s ease; }
    .kp-x:hover { translate: 0 -3px; box-shadow: 0 1px 2px rgba(20, 38, 83, .05), 0 22px 56px rgba(20, 38, 83, .13); }
}
.kp-x-art {
    height: 400px; overflow: hidden; display: flex; justify-content: center; align-items: center; padding: 0 32px;
    background: radial-gradient(ellipse 70% 60% at 50% 0%, rgba(0, 113, 252, .1), transparent 70%), linear-gradient(180deg, #f5f8fd, #fff);
}
/* A mock taller than its window starts at the top and runs off the foot. */
.kp-x-art-top { align-items: flex-start; padding-top: 36px; -webkit-mask-image: linear-gradient(#000 80%, transparent); mask-image: linear-gradient(#000 80%, transparent); }
.kp-x-art-phone { align-items: flex-end; }
.kp-x-art-phone .ph-panel { height: 364px; box-shadow: 0 20px 50px rgba(8, 28, 64, .18); }
.kp-x-cap { padding: 24px 32px 30px; }
.kp-x-cap h3 { font-size: 19px; }
.kp-x-cap p { margin-top: 8px; max-width: 460px; color: var(--muted); font-size: 15px; text-wrap: pretty; }
.kp-x-cap .kp-text-link { margin-top: 16px; font-size: 14px; }

/* Mock pieces shared by the explore cards: a small label, a list of rows
   with an icon, a name, a detail and a control at the far end. */
.kp-ui { width: min(420px, 100%); font-size: 14px; }
.kp-ui-label { margin: 0 0 6px 4px; font-size: 12px; font-weight: 500; color: var(--dim); }
.kp-ui-rows { list-style: none; margin: 0; padding: 0; }
.kp-ui-rows li { position: relative; display: flex; align-items: center; gap: 12px; padding: 11px 4px; font-weight: 500; white-space: nowrap; }
.kp-ui-rows li + li { border-top: 1px solid var(--line); }
.kp-ui-rows .is-soon { color: var(--dim); }
.kp-ui-ico { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 8px; background: var(--panel-2); border: 1px solid var(--line); color: var(--muted); font-size: 16px; }
.kp-ui-ico-green { background: #34c759; border-color: #34c759; color: #fff; font-variation-settings: 'FILL' 1; }
.kp-ui-meta { margin-left: auto; overflow: hidden; text-overflow: ellipsis; font: 400 12.5px/1 var(--mono); color: var(--dim); }
.kp-toggle { flex: none; position: relative; width: 34px; height: 20px; border-radius: 10px; background: #dfe3ec; }
.kp-toggle::after { content: ''; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(20, 38, 83, .25); }
.kp-toggle.on { background: #34c759; }
.kp-toggle.on::after { left: 16px; }
.kp-sync { flex: none; display: inline-flex; align-items: center; gap: 6px; min-width: 66px; font-size: 12px; color: var(--dim); }
.kp-sync::before { content: ''; width: 10px; height: 10px; border-radius: 50%; border: 1.5px solid var(--line-2); border-top-color: var(--blue); animation: kp-spin 1s linear infinite; }
.kp-sync.is-done { color: #15803d; }
.kp-sync.is-done::before { border-color: #34c759; background: #34c759; animation: none; }
@keyframes kp-spin { to { transform: rotate(360deg); } }
/* The box the job is typed into, with a caret still blinking at its end. */
.kp-prompt { display: flex; align-items: flex-end; gap: 12px; margin-bottom: 22px; padding: 14px 14px 14px 16px; border-radius: 16px; background: #fff; border: 1px solid var(--line-2); box-shadow: var(--card-shadow); font-size: 15px; line-height: 1.45; }
.kp-prompt i { display: inline-block; width: 1.5px; height: 1.1em; margin-left: 2px; vertical-align: -.18em; background: var(--blue); animation: kp-caret 1.1s steps(1) infinite; }
@keyframes kp-caret { 50% { opacity: 0; } }
.kp-prompt .material-symbols-outlined { display: grid; place-items: center; width: 28px; height: 28px; margin-left: auto; border-radius: 50%; background: var(--blue); color: #fff; font-size: 17px; }

/* Work log: one morning's actions scrolling by. The list is written twice
   in the HTML, so sliding the track up by half its height lands exactly on
   the first copy again: a seamless loop with no script. Hover pauses it so
   a step can be read. */
.kp-feed { width: min(440px, 100%); }
.kp-feed-head { display: flex; align-items: center; gap: 9px; padding: 0 6px 12px; }
.kp-feed-head i { width: 8px; height: 8px; border-radius: 50%; background: #34c759; animation: kp-ping 2s infinite; }
@keyframes kp-ping { 0% { box-shadow: 0 0 0 0 rgba(52, 199, 89, .55); } 70%, 100% { box-shadow: 0 0 0 9px rgba(52, 199, 89, 0); } }
.kp-feed-view { height: 340px; overflow: hidden; }
.kp-feed-track { list-style: none; margin: 0; padding: 0; animation: kp-feed 56s linear infinite; }
.kp-feed-view:hover .kp-feed-track { animation-play-state: paused; }
@keyframes kp-feed { to { transform: translateY(-50%); } }
.kp-step { margin-bottom: 8px; padding: 10px 12px; border-radius: 14px; background: #fff; border: 1px solid var(--line); box-shadow: 0 1px 2px rgba(20, 38, 83, .04); }
.kp-step-head { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 500; }
.kp-step-head .material-symbols-outlined { font-size: 18px; color: var(--blue); }
.kp-step-head time { margin-left: auto; font: 400 12px/1 var(--mono); color: var(--dim); }
.kp-step-body { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin-top: 5px; font-size: 14px; color: var(--muted); }
.kp-step-msg .kp-step-body { display: inline-flex; margin-top: 7px; padding: 6px 11px; border-radius: 14px 14px 14px 4px; background: #e9e9eb; color: #000; font: 400 13.5px/1.3 var(--ios); }

/* The code panel stays dark on the light page, like an editor window. */
.kp-code { width: min(480px, 100%); margin: 0; border-radius: 16px; background: #0e1322; border: 1px solid #1e2539; overflow: hidden; box-shadow: 0 24px 60px rgba(20, 38, 83, .24); }
.kp-code figcaption { display: flex; align-items: center; gap: 12px; padding: 13px 16px; border-bottom: 1px solid #1e2539; font: 500 12px/1 var(--mono); color: #8a93ab; }
.kp-dots { display: inline-flex; gap: 6px; }
.kp-dots i { width: 10px; height: 10px; border-radius: 50%; background: #2a2a2e; }
.kp-status-chips { margin-left: auto; display: flex; gap: 6px; }
.kp-sc { display: inline-flex; align-items: center; gap: 5px; padding: 4px 8px; border-radius: 6px; background: #161c2e; border: 1px solid #252c40; font-size: 11px; color: #8a93ab; }
.kp-sc::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--dim); }
.kp-sc-green::before { background: #34c759; }
.kp-sc-blue::before { background: var(--blue); }
.kp-code pre { margin: 0; padding: 20px; overflow: hidden; font: 400 13px/1.7 var(--mono); color: #e4e4e7; }
.kp-code .c { color: #63636b; }
.kp-code .k { color: #c792ea; }
.kp-code .s { color: #a5d98a; }
.kp-code .f { color: var(--blue-soft); }
.kp-code .n { color: #f2c46d; }
.kp-code-foot { padding: 0 20px 18px; font: 400 11px/1 var(--mono); color: var(--dim); }

/* Inbox: a list of chats, the one handed to you lifted off the rest. */
.kp-inbox { list-style: none; width: min(680px, 100%); margin: 0; padding: 0; font-size: 14px; }
.kp-inbox li { display: flex; align-items: center; gap: 14px; padding: 13px 18px; border-radius: 14px; white-space: nowrap; opacity: .55; }
.kp-inbox li:first-child, .kp-inbox li:last-child { opacity: .3; }
.kp-inbox li.is-on { margin: 6px -14px; padding: 16px 32px; background: #fff; border: 1px solid var(--line); box-shadow: var(--card-shadow); opacity: 1; }
.kp-inbox b { flex: none; width: 84px; font-weight: 600; }
.kp-in-av { display: grid; place-items: center; flex: none; width: 28px; height: 28px; border-radius: 50%; background: var(--panel-2); border: 1px solid var(--line-2); font-size: 12px; font-weight: 600; color: var(--muted); }
.kp-in-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--muted); }
.kp-inbox time { flex: none; width: 30px; text-align: right; font: 400 12px/1 var(--mono); color: var(--dim); }

/* A slice of one thread with its controls. Bubbles are sized in em, so the
   wrapper's font size sets them (11px gives a 14px bubble). */
.kp-chat { display: flex; flex-direction: column; gap: 7px; font: 11px/1.3 var(--ios); }
.kp-chat .b { max-width: 82%; }
.kp-ui-status { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; font: 500 12.5px/1 var(--sans); color: var(--muted); }
.kp-ui-status i { width: 7px; height: 7px; border-radius: 50%; background: #34c759; }
.kp-ui-by { font: 400 11.5px/1 var(--sans); color: var(--dim); }
.kp-ui-by:has(+ .kp-seg) { align-self: flex-end; }
.kp-seg { align-self: flex-start; display: inline-flex; gap: 2px; margin-top: 14px; padding: 3px; border-radius: 10px; background: var(--panel-2); border: 1px solid var(--line); font: 500 12.5px/1 var(--sans); color: var(--dim); }
.kp-seg span { padding: 6px 10px; border-radius: 7px; }
.kp-seg .on { background: #fff; color: var(--text); box-shadow: 0 1px 2px rgba(20, 38, 83, .12); }
.kp-compose { display: flex; align-items: center; gap: 10px; padding: 10px 10px 10px 14px; border-radius: 14px; background: #fff; border: 1px solid var(--line-2); box-shadow: var(--card-shadow); font: 400 14px/1.35 var(--sans); }
.kp-compose .material-symbols-outlined { display: grid; place-items: center; width: 26px; height: 26px; margin-left: auto; border-radius: 50%; background: var(--blue); color: #fff; font-size: 16px; }
.kp-alert { display: flex; align-items: center; gap: 12px; margin-top: 16px; padding: 12px 14px; border-radius: 14px; background: #fff; border: 1px solid var(--line); box-shadow: var(--card-shadow); font: 400 14px/1.3 var(--sans); }
.kp-alert > span:nth-child(2) { display: flex; flex-direction: column; min-width: 0; }
.kp-alert b { font-weight: 600; }
.kp-alert small { font-size: 12.5px; color: var(--muted); }
.kp-alert mark { margin-left: auto; }

/* The pay sheet that rises over the thread when a pay card is tapped. */
.kp-paysheet { margin-top: 8px; padding: 6px 18px 16px; border-radius: 20px; background: #fff; border: 1px solid var(--line); box-shadow: 0 1px 2px rgba(20, 38, 83, .06), 0 18px 44px rgba(20, 38, 83, .14); font: 400 13px/1.3 var(--ios); color: #000; }
.kp-paysheet p { display: flex; align-items: center; gap: 12px; padding: 12px 0; }
.kp-paysheet p + p { border-top: 1px solid #ececf0; }
.kp-pay-head b { font-size: 17px; font-weight: 700; letter-spacing: -.01em; }
.kp-pay-head .material-symbols-outlined { display: grid; place-items: center; width: 24px; height: 24px; margin-left: auto; border-radius: 50%; background: #ececf0; color: #6b6b70; font-size: 15px; }
.kp-pay-row > span:first-child, .kp-pay-row small { color: #8e8e93; }
.kp-pay-row span:has(small) { display: flex; flex-direction: column; color: #000; }
.kp-pay-row > :last-child { margin-left: auto; }
.kp-pay-row b { font-weight: 500; }
.kp-pay-row .material-symbols-outlined { color: #c4c4c8; }
.kp-pay-card { width: 34px; height: 22px; border-radius: 4px; background: linear-gradient(135deg, #1d3a6e, #0071fc); }
.kp-pay-total b { font-size: 20px; font-weight: 600; letter-spacing: -.02em; }
.kp-paysheet .kp-pay-confirm { flex-direction: column; gap: 6px; padding-bottom: 0; font-size: 12px; }
.kp-pay-confirm .material-symbols-outlined { font-size: 30px; color: var(--imsg); }

/* FAQ */
.kp-faq h2 { text-align: center; }
.kp-faq-list { max-width: 820px; margin: 40px auto 0; display: grid; gap: 10px; }
.kp-faq details { border-radius: 14px; background: var(--panel); border: 1px solid var(--line); box-shadow: var(--card-shadow); padding: 0 22px; transition: border-color .2s ease; }
.kp-faq details:hover { border-color: var(--line-2); }
.kp-faq summary { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 20px 0; cursor: pointer; list-style: none; font-size: 16px; font-weight: 500; }
.kp-faq summary::-webkit-details-marker { display: none; }
.kp-faq summary::after { content: '+'; font: 300 24px/1 var(--sans); color: var(--muted); transition: transform .2s ease; }
.kp-faq details[open] summary::after { transform: rotate(45deg); }
.kp-faq details p { padding: 0 0 20px; color: var(--muted); animation: kp-step .3s ease backwards; }

/* Close: form + demo on a panel of sky */
.kp-close { position: relative; isolation: isolate; overflow: hidden; margin: clamp(88px, 12vw, 160px) 16px 0; border-radius: 28px; background: var(--blue-panel); }
.kp-close-inner { max-width: 1180px; margin: 0 auto; padding: clamp(48px, 7vw, 88px) clamp(20px, 4vw, 56px); display: grid; grid-template-columns: 1.4fr .6fr; column-gap: 28px; }
/* The copy wrapper steps aside so its headline spans the row and its form
   shares a row with the demo card. */
.kp-close-copy { display: contents; }
.kp-close-copy h2, .kp-close-copy > p { grid-column: 1 / -1; }
.kp-close-copy h2 { background: none; color: #fff; }
.kp-close-copy > p { margin-top: 14px; color: rgba(255, 255, 255, .88); font-size: 17px; }
#kp-form { grid-column: 1; display: grid; gap: 14px; margin-top: 28px; padding: 24px; border-radius: 20px; background: #fff; box-shadow: 0 24px 60px rgba(0, 25, 90, .25); }
.kp-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
#kp-form label { display: grid; gap: 6px; font-size: 13px; font-weight: 500; color: var(--text); }
#kp-form input, #kp-form textarea, #kp-form select {
    width: 100%; padding: 11px 13px; border-radius: 10px; border: 1px solid var(--line-2);
    background: var(--panel-2); color: var(--text); font: 400 15px/1.4 var(--sans);
}
#kp-form textarea { resize: vertical; }
#kp-form input:focus, #kp-form textarea:focus, #kp-form select:focus { outline: 2px solid var(--blue); outline-offset: 1px; }
.kp-form-foot { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.kp-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.kp-form-msg { font-size: 14px; color: var(--muted); }
.kp-form-msg.is-ok { color: #16a34a; font-weight: 500; }
.kp-form-msg.is-error { color: #dc2626; }
.kp-demo {
    grid-column: 2; margin-top: 28px;
    display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 0;
    padding: 28px 22px; border-radius: 20px; background: #fff; box-shadow: 0 24px 60px rgba(0, 25, 90, .25);
}
.kp-demo h3 { margin-top: 10px; font: 400 23px/1.2 var(--display); }
.kp-qr { margin-top: 20px; padding: 10px; border-radius: 16px; background: #fff; border: 1px solid var(--line); }
.kp-qr-hint { margin: 10px 0 18px; font-size: 12px; color: var(--muted); }

/* Footer: a dark band. The small print on top, then the wordmark very
   large. The whole word is one mask (the logo's own shape): behind it the
   V is a window of sky with the halftone clouds in it, and the letters
   are a grey barely lighter than the band. */
.kp-footer { margin-top: clamp(80px, 11vw, 140px); overflow: hidden; border-radius: 28px 28px 0 0; background: #0a0b0f; color: #8b90a0; font-size: 14px; }
.kp-footer-top { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; max-width: 1180px; margin: 0 auto; padding: 40px 24px 0; }
.kp-footer nav { display: flex; gap: 20px; }
.kp-footer a { text-decoration: none; }
.kp-footer p a, .kp-footer nav a:hover { color: #fff; }
.kp-word {
    position: relative; isolation: isolate; width: min(1400px, calc(100% - 48px)); aspect-ratio: 2029 / 417; margin: clamp(40px, 7vw, 96px) auto clamp(32px, 5vw, 72px);
    background: linear-gradient(90deg, transparent 25.3%, #24272f 25.3%), var(--blue-panel);
    -webkit-mask: url(/images/vanquel/vanquel-wordmark-mask.png?v=1) center / 100% 100% no-repeat; mask: url(/images/vanquel/vanquel-wordmark-mask.png?v=1) center / 100% 100% no-repeat;
}
.kp-word .kp-clouds { width: 25.3%; }

/* ── Mocks that play ──────────────────────────────────────────────────
   A [data-play] mock arrives a piece at a time: its children come in one
   after another (bubbles and cards pop from their own corner, everything
   else steps up), and a few mocks add beats of their own below. Every
   keyframe only says where a thing comes FROM, so the finished mock is
   what the plain styles describe. Left alone, a sequence just runs on
   load. phone-landing.ts holds each one on its first frame (.is-armed)
   until the mock is on screen (.is-playing), so it is seen, once. With no
   script, or with reduced motion, nothing is armed and nothing is hidden. */
@keyframes kp-step { from { opacity: 0; translate: 0 10px; } }
@keyframes kp-say { from { opacity: 0; scale: .88; translate: 0 .5em; } }
@keyframes kp-sheet { from { opacity: 0; translate: 0 48px; } }
@keyframes kp-tap { from { opacity: 0; scale: .4; } }
@keyframes kp-out { from { opacity: 1; } }
@keyframes kp-wait { 0% { opacity: 0; scale: .8; } 30%, 80% { opacity: 1; scale: 1; } 100% { opacity: 0; scale: 1; } }
@keyframes kp-ticking { from { opacity: 1; rotate: 0turn; } 90% { opacity: 1; } to { opacity: 0; rotate: 1.5turn; } }
@keyframes kp-knob { from { translate: -14px 0; } }
@keyframes kp-press { 50% { scale: .84; } }
[data-play] > * { animation: kp-step .5s cubic-bezier(.2, .7, .2, 1) var(--d, 0s) backwards; }
[data-play] > .b, [data-play] > .ph-card { animation-name: kp-say; animation-duration: .4s; transform-origin: 0 100%; }
[data-play] > .b.me { transform-origin: 100% 100%; }
[data-play] > :nth-child(1) { --d: .1s; }
[data-play] > :nth-child(2) { --d: .32s; }
[data-play] > :nth-child(3) { --d: .54s; }
[data-play] > :nth-child(4) { --d: .76s; }
[data-play] > :nth-child(5) { --d: .98s; }
[data-play] > :nth-child(6) { --d: 1.2s; }
[data-play] > :nth-child(7) { --d: 1.42s; }
[data-play] > :nth-child(8) { --d: 1.64s; }

/* The hero thread keeps its own time: a text, the typing bubble, the reply
   and its card, and so on down to the heart, the receipt and the dots. */
.kp-phones [data-play] > :nth-child(1) { --d: .3s; }
.kp-phones [data-play] > :nth-child(2) { --d: .55s; }
.kp-phones [data-play] > :nth-child(3) { --d: .95s; }
.kp-phones [data-play] > :nth-child(4) { --d: 1.1s; }
.kp-phones [data-play] > :nth-child(5) { --d: 1.45s; }
.kp-phones [data-play] > :nth-child(6) { --d: 1.7s; }
.kp-phones [data-play] > :nth-child(7) { --d: 2.1s; }
.kp-phones [data-play] > :nth-child(8) { --d: 2.25s; }
.kp-phones [data-play] > :nth-child(9) { --d: 2.6s; }
.kp-phones [data-play] > :nth-child(10) { --d: 2.9s; }
.kp-phones [data-play] > :nth-child(11) { --d: 3.05s; }
[data-play] > .ph-wait { animation: none; }
[data-play] > .ph-wait::before { animation: kp-wait .45s ease var(--d); }
[data-play] .ph-tap { animation: kp-tap .4s cubic-bezier(.3, 1.4, .5, 1) 2.85s backwards; }

/* Describe the job: the prompt arrives a word at a time (phone-landing.ts
   wraps each word and numbers it with --i), the caret and a press of the
   send button follow, then the channels, and iMessage switches on. */
.kp-prompt span span { animation: kp-in-fade .3s ease calc(.3s + var(--i) * .05s) backwards; }
[data-play] .kp-prompt i { animation: kp-caret 1.1s steps(1) infinite, kp-in-fade .01s 1.05s backwards; }
[data-play] .kp-prompt .material-symbols-outlined { animation: kp-press .4s ease 1.1s; }
[data-play] > .kp-prompt ~ .kp-ui-label { --d: 1.2s; }
[data-play] > .kp-prompt ~ .kp-ui-rows { --d: 1.3s; }
[data-play] .kp-toggle.on::before { content: ''; position: absolute; inset: 0; border-radius: inherit; background: #dfe3ec; opacity: 0; animation: kp-out .3s ease 1.8s backwards; }
[data-play] .kp-toggle.on::after { animation: kp-knob .3s cubic-bezier(.2, .7, .2, 1) 1.8s backwards; }
[data-play] li:has(.kp-toggle.on) .kp-ui-meta { animation: kp-in-fade .4s ease 2s backwards; }

/* Sources: the first three rows spin for --t, one longer than the last,
   then each turns to Synced in turn. The spinner is the row's own
   ::after, laid where the green dot will be. */
.kp-ui-rows[data-play] > :nth-child(1) { --t: .9s; }
.kp-ui-rows[data-play] > :nth-child(2) { --t: 1.25s; }
.kp-ui-rows[data-play] > :nth-child(3) { --t: 1.6s; }
[data-play] > li:has(.is-done)::after {
    content: ''; position: absolute; right: 60px; top: 50%; width: 10px; height: 10px; margin-top: -5px; border-radius: 50%;
    border: 1.5px solid var(--line-2); border-top-color: var(--blue); opacity: 0; animation: kp-ticking var(--t) linear backwards;
}
[data-play] .kp-sync.is-done { animation: kp-in-pop .35s ease var(--t) backwards; }

/* Inbox: once the rows are in, the chat handed to you gets its tag.
   Deposit: the pay sheet slides up over the thread, then Face ID lands. */
.kp-inbox[data-play] .is-on mark { animation: kp-in-pop .4s ease 1.3s backwards; }
[data-play] > .kp-paysheet { --d: .95s; animation-name: kp-sheet; animation-duration: .6s; }
[data-play] .kp-pay-confirm .material-symbols-outlined { animation: kp-tap .45s cubic-bezier(.3, 1.4, .5, 1) 1.65s backwards; }

.is-armed:not(.is-playing) *, .is-armed:not(.is-playing) *::before, .is-armed:not(.is-playing) *::after { animation-play-state: paused !important; }

/* ── Scroll reveal ────────────────────────────────────────────────────
   CSS-only, tied to scroll position. A browser without scroll timelines
   simply shows everything: nothing here can ever leave a section hidden.
   Where cards sit two to a row, the right-hand one rises a beat later. */
@keyframes kp-rise { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: none; } }
@supports (animation-timeline: view()) {
    [data-reveal] { animation: kp-rise linear both; animation-timeline: view(); animation-range: entry 0% cover 18%; }
    @media (min-width: 1024px) {
        .kp-xgrid:not(:has(.kp-x-wide)) > :nth-child(even), .kp-x-wide + .kp-x + .kp-x { animation-range: entry 12% cover 30%; }
    }
}
@media (prefers-reduced-motion: reduce) {
    [data-reveal], .ph-typing i, .kp-frag, .kp-feed-head i, .kp-feed-track, .kp-sync::before, .kp-prompt i,
    .kp-hero h1, .kp-chips, .kp-hero-ctas, .kp-nav, .kp-band, .kp-phones .ph, .kp-panel-copy, .kp-panel > .ph, .kp-mail, .kp-faq details p,
    [data-play] *, [data-play] *::before, [data-play] *::after { animation: none; }
    .kp-phones .ph, .kp-clouds, .kp-frag, .kp-x, .kp-pill { transition: none; }
}

/* ── Tablet ───────────────────────────────────────────────────────────── */
@media (max-width: 1199px) {
    .ph-side { display: none; }
    .kp-phones { height: 720px; }
}
@media (max-width: 1023px) {
    .kp-links { display: none; }
    .kp-close-inner { grid-template-columns: 1fr; }
    .kp-demo { grid-column: 1; }
    .kp-panel { grid-template-columns: 1fr; padding: 40px 32px 0; }
    .kp-panel-copy { padding-bottom: 8px; }
    .kp-mail { margin-top: 24px; }
    .kp-xgrid { grid-template-columns: 1fr; }
}

/* ── Phone ────────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
    .kp-nav { top: 10px; padding-left: 14px; }
    .kp-icon-btn { display: none; }
    .kp-hero { padding-top: 112px; }
    /* One short exchange above the headline stands in for the scattered pieces. */
    .kp-frags { position: static; display: flex; width: 100%; max-width: 360px; margin: 0 auto 26px; }
    .kp-frag { display: none; }
    .kp-frag-ml { position: static; display: flex; width: 100%; transform: none; animation: kp-in .6s cubic-bezier(.2, .7, .2, 1) backwards; }
    .kp-hero h1 br, h2 br { display: none; }
    /* Sized so the headline breaks in two even lines, never a word alone. */
    .kp-hero h1 { font-size: 10.6vw; }
    .kp-chips { gap: 8px 14px; font-size: 14px; }
    .kp-chips li:last-child { display: none; }
    .kp-hero-ctas { flex-direction: column; gap: 16px; width: 100%; }
    .kp-hero-ctas .kp-pill { width: 100%; justify-content: center; }
    .kp-phones { width: calc(100% + 32px); height: 600px; margin: 22px -16px 0; border-radius: 0 0 26px 26px; }
    .kp-band { inset: 76px 0 0; border-radius: 26px; }
    .ph-center { --w: min(320px, calc(100vw - 56px)); }
    .kp-section { padding-left: 16px; padding-right: 16px; }
    .kp-tabs { flex-wrap: nowrap; justify-content: flex-start; align-self: stretch; overflow-x: auto; margin-left: -16px; margin-right: -16px; padding: 0 16px; scrollbar-width: none; }
    .kp-tabs::-webkit-scrollbar { display: none; }
    .kp-tabs button { flex: none; }
    .kp-panel { padding: 30px 22px 0; }
    .ph-panel { --w: 250px; height: 380px; }
    .kp-mail { margin-bottom: 30px; }
    .kp-xgrid { gap: 14px; margin-top: 36px; }
    .kp-x-art { height: 360px; padding: 0 16px; }
    .kp-x-art-top { padding-top: 26px; }
    .kp-x-art-phone .ph-panel { height: 330px; }
    .kp-x-cap { padding: 20px 20px 24px; }
    .kp-ui-rows li { gap: 9px; font-size: 13.5px; }
    .kp-feed-view { height: 310px; }
    .kp-code pre { font-size: 11px; padding: 16px; }
    .kp-status-chips { display: none; }
    /* The inbox keeps the name, the status and the time; the preview line goes. */
    .kp-inbox li { gap: 10px; padding: 12px 10px; }
    .kp-inbox li.is-on { margin: 6px 0; padding: 14px 12px; }
    .kp-in-text { visibility: hidden; }
    .kp-row { grid-template-columns: 1fr; }
    .kp-close { margin-left: 8px; margin-right: 8px; }
    #kp-form { padding: 18px; }
    .kp-form-foot .kp-pill { width: 100%; justify-content: center; }
    .kp-qr, .kp-qr-hint { display: none; }
    .kp-demo h3 { margin-bottom: 18px; }
}
