/* Signature designs (public/designs.js), shared by the pages and the GIF recorder (lib/animated.js): the customers' designs
   (.cp, .m-<motion>, at the end). --acc is the accent of the person on the root .rs;
   decorative gradients stay fixed. Every cycle divides the GIF's 4.8 s loop (lib/gif.js would fit it to one), so a page
   plays exactly what the GIF plays. */
/* ====== shared ====== */
.rs { --c: #111; font-family: "Geist", Arial, sans-serif; color: #111; width: 100%; max-width: 380px; min-width: 0; text-align: left; position: relative; }
.rs .row { display: flex; gap: 18px; align-items: center; }
.rs .ph { width: 80px; height: 80px; border-radius: 50%; object-fit: cover; display: block; position: relative; z-index: 1; flex: none; }
.rs .nm { font-size: 18px; font-weight: 600; letter-spacing: -0.03em; line-height: 1.15; }
.rs .rl { font-size: 12.5px; color: #6e6e73; margin-top: 3px; }
/* the labels share one column as wide as the longest (es "correo"), at least 34 px; each row stays a box of its own */
.rs .ct { font-size: 12px; color: #3a3a3c; display: grid; grid-template-columns: minmax(34px, max-content) minmax(0, 1fr); gap: 3px 0; margin-top: 12px; }
.rs .ct > * { display: grid; grid-template-columns: subgrid; grid-column: 1 / -1; }
.rs .ct b { font-weight: 500; color: #a1a1a6; padding-right: 6px; }
.rs .soc { display: flex; gap: 7px; margin-top: 12px; }
.rs .soc i { width: 26px; height: 26px; border-radius: 8px; display: grid; place-items: center; background: var(--c); color: #fff; }
.rs .soc i svg { width: 13px; height: 13px; display: block; }
/* photo slot without a photo: the logo as a mark, else initials; a logo next to a photo goes under the signature */
.rs .ph.mark { object-fit: contain; background: #fff; border-radius: 18px; }
.rs .ph.mono { display: grid; place-items: center; background: var(--acc); color: #fff; font-weight: 600; font-size: 24px; letter-spacing: -.02em; }
.rs .bm { display: block; max-height: 24px; max-width: 140px; margin-top: 12px; }
/* a white or nearly white logo (designs.js logoTile) on a tile of the brand colour or near-black: on white it vanished */
.rs .on-tile, .rs .ph.mark.on-tile { background: var(--tile); }
.rs .ph.mark.on-tile { box-sizing: border-box; padding: 12%; }
.rs .bm.on-tile { box-sizing: content-box; padding: 6px 10px; border-radius: 8px; }
/* each platform's own colours ride on its icon (public/platforms.js brandVars): the brand colour, a multicolour tile, a dark mark */
.rs .soc.brand i { background: var(--pg, var(--pc)); color: var(--pi, #fff); }
/* a link's site icon (lib/site-icon.js): an opaque square, filling the tile like an app icon */
.rs .soc i[data-k="site"] { overflow: hidden; } .rs .soc i[data-k="site"] img { width: 100%; height: 100%; display: block; border-radius: inherit; }
.rs .soc.pulse i { animation: tap 2.4s ease-in-out infinite; }
.rs .soc.pulse i:nth-child(2) { animation-delay: .22s; } .rs .soc.pulse i:nth-child(3) { animation-delay: .44s; } .rs .soc.pulse i:nth-child(4) { animation-delay: .66s; } .rs .soc.pulse i:nth-child(5) { animation-delay: .88s; }
@keyframes tap { 0%, 30%, 100% { transform: scale(1); } 12% { transform: scale(1.28); } 20% { transform: scale(.94); } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes ping { 0% { box-shadow: 0 0 0 0 rgba(40,200,64,.6); } 80%, 100% { box-shadow: 0 0 0 7px rgba(40,200,64,0); } }

/* ====== the customers' designs (DESIGNS): three low layouts, a motion each ======
   One geometry for every motion: the photo slot is the same 64 px box in every layout (a 56 px photo and room for its accent), so a motion
   never moves the layout, and the text column keeps room at the end of its last line for the "Save contact" button. Every
   first frame is the whole signature at rest (Outlook shows only that one). */
.cp { --cp-ph: 56px; --cp-slot: 64px; --cp-gap: 16px; --cp-logo: 22px; width: fit-content; max-width: 380px; overflow-wrap: anywhere; } /* a word too long for its place breaks, never past the frame */
.cp .cp-row { display: flex; align-items: center; gap: var(--cp-gap); } /* the photo beside the words, which wrap (the editor makes it wrap once it takes a part) */
.cp .cp-slot { position: relative; flex: none; width: var(--cp-slot); height: var(--cp-slot); display: grid; place-items: center; }
.cp .cp-slot > * { grid-area: 1 / 1; }
.cp .ph { width: var(--cp-ph); height: var(--cp-ph); }
.cp .ph.mono { font-size: 21px; }
.cp .ph.mark { border-radius: 14px; }
.cp .cp-tx { min-width: 248px; } /* no box is squeezed below what it holds: what does not fit goes to a next line (min-width: auto) */
/* Nothing is ever hidden or cut short (owner 2026-11-11, which replaces "one line each, a long one ends in an ellipsis"):
   a long name or title wraps, the contacts wrap to a next line, the signature grows instead (the GIF's frame keeps its
   width). The contacts in a line, a dot between. Nothing here clips: their words never reach past their box, and their
   own effects – a typewriter's cursor, an underline, a line above, a sparkle – paint all around them (the GIF's frame
   gives the design MARGIN, designs.js, and fades its edge), as does a part moved or turned into them. A flow-root keeps
   the room a part turned in a line takes (its margins) in that line. */
.cp .nm { display: flow-root; font-size: 16px; line-height: 20px; letter-spacing: -0.02em; overflow-wrap: anywhere; }
.cp .rl { display: flow-root; font-size: 12px; line-height: 16px; margin-top: 2px; overflow-wrap: anywhere; }
.cp .ct { display: flex; flex-wrap: wrap; row-gap: 2px; margin-top: 6px; font-size: 12px; line-height: 16px; }
.cp .ct > span { display: block; overflow-wrap: anywhere; } /* its lines: a box moved in among them keeps its own look */
.cp .ct > span + span::before { content: "·"; margin: 0 7px; color: #c7c7cc; }
.cp .ct > :not(span) { margin: 0 8px; } .cp .ct > :not(span):first-child { margin-left: 0; } /* a box moved in among them keeps apart */
/* the last line: the icons, the logo small and inline, the button */
/* 2px of room for a pulse (fx-heartbeat strong swells a 20px item by ~2px), given back by the margins: the card keeps its height */
.cp .cp-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; min-height: 24px; margin: 7px 0 -1px; }
.cp .soc { margin-top: 0; gap: 6px 5px; flex-shrink: 8; flex-wrap: wrap; } /* what does not fit goes to a next line */
.cp .soc i { width: 20px; height: 20px; border-radius: 6px; background: var(--acc); }
.cp .soc i svg { width: 11px; height: 11px; }
.cp .bm { flex: 0 1 auto; display: block; margin: 0; height: var(--cp-logo); width: auto; max-height: none; max-width: 120px; object-fit: contain; object-position: left center; }
.cp .bm.on-tile { height: calc(var(--cp-logo) - 8px); padding: 4px 8px; border-radius: 6px; }
/* margin: the page's own .cta row (styles.css) would push the button 36px down in the panel */
.cp .cta { flex: none; display: inline-flex; margin: 0; align-items: center; height: 22px; padding: 0 10px; border-radius: 999px; background: var(--acc); color: #fff; font-size: 11px; font-weight: 600; white-space: nowrap; }

/* every layout as high as itself at least (designs.js LAYOUTS): lines he has not filled leave the others centred beside
   the photo; more than fits makes it grow (nothing hidden) */
.cp-classic .cp-row { min-height: 90px; }
.cp-classic .cp-foot { min-height: 24px; }
/* card: the name and title with the logo on their right; under a hairline the contacts and, at their end, the icons */
.cp-card { width: 380px; }
.cp-card .cp-row { min-height: 76px; }
.cp-card .cp-tx { flex: 1; }
.cp-card .cp-top, .cp-card .cp-bottom { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; }
.cp-card .cp-who { flex: 1; }
.cp-card .cp-top .bm { flex: none; max-width: 110px; }
.cp-card .cp-bottom { min-height: 22px; margin-top: 8px; padding-top: 7px; border-top: 1px solid #ececef; box-sizing: content-box; }
.cp-card .cp-bottom .ct { flex: 1 1 auto; margin-top: 0; } /* the contacts take the line they need: the icons and the button go under them, an address never breaks */
.cp-card .cp-end { flex: 0 1 auto; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
/* columns: the name, the title and the logo; beside them, after a line in the brand colour, the contacts on lines of their
   own, then the button and the icons */
.cp-columns { width: 380px; }
.cp-columns .cp-row { min-height: 66px; }
.cp-columns .cp-who { flex: 1 1 auto; }
.cp-columns .cp-who .bm { margin-top: 6px; max-width: 110px; }
.cp-columns .cp-reach { flex: 0 1 auto; max-width: 200px; align-self: stretch; display: flex; flex-direction: column; justify-content: center; gap: 6px; padding-left: 14px; border-left: 2px solid var(--acc); } /* wide enough for an e-mail address in one line */
.cp-columns .ct { display: block; margin-top: 0; }
.cp-columns .ct > span { line-height: 18px; }
.cp-columns .ct > span + span::before { content: none; }
.cp-columns .cp-end { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-height: 22px; }
.cp-columns .cp-end:empty { display: none; }
.cp-columns .cp-end .soc { flex: 1 1 0; }

/* the hand that shows the signature can be clicked (designs.js cpHint): it glides in to the photo, clicks it with a ripple
   in the brand colour and glides away, once per loop – nowhere in the first frame, and nowhere while nothing plays */
.cp .cp-hint { position: absolute; left: 47px; top: 45px; width: 0; height: 0; z-index: 3; pointer-events: none; }
.cp .cp-hint-hand { position: absolute; left: -6px; top: -2px; width: 19px; height: 19px; overflow: visible; opacity: 0; transform-origin: 6px 2px; fill: #fff; stroke: #1d1d1f; stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; filter: drop-shadow(0 1px 1.2px rgba(0, 0, 0, .28)); animation: cp-hint-hand 4.8s infinite; }
.cp .cp-hint-crease { fill: none; }
.cp .cp-hint-ring { position: absolute; left: -13px; top: -13px; width: 26px; height: 26px; border-radius: 50%; border: 2px solid var(--acc); background: color-mix(in srgb, var(--acc) 16%, transparent); box-sizing: border-box; opacity: 0; animation: cp-hint-ring 4.8s infinite; }
@keyframes cp-hint-hand {
  0%, 36% { opacity: 0; transform: translate(var(--cp-hx, 26px), var(--cp-hy, 20px)); animation-timing-function: cubic-bezier(.2, .7, .3, 1); }
  50% { opacity: 1; transform: translate(0, 0); animation-timing-function: ease-in-out; }
  54% { opacity: 1; transform: translate(0, 0) scale(.84); animation-timing-function: ease-out; }
  59%, 66% { opacity: 1; transform: translate(0, 0); animation-timing-function: cubic-bezier(.5, 0, .75, 0); }
  80%, 100% { opacity: 0; transform: translate(var(--cp-lx, 20px), var(--cp-ly, 24px)); }
}
@keyframes cp-hint-ring {
  0%, 54% { opacity: 0; transform: scale(.2); }
  55% { opacity: .9; transform: scale(.3); animation-timing-function: cubic-bezier(.2, .7, .3, 1); }
  74%, 100% { opacity: 0; transform: scale(1.15); }
}
/* the hand on another part he named (designs.js compact: .cp-hint-at holds it – the button itself, a box around the logo,
   the name's own block): the point it clicks inside that part, and the way it comes and goes – from above on the bottom
   line, so it stays inside the GIF's frame */
.cp .cp-hint-at { position: relative; }
.cp .cp-bmw { display: flex; flex: 0 1 auto; min-width: 0; width: fit-content; max-width: 100%; }
.cp-card .cp-top .cp-bmw { flex: none; }
.cp .cp-hint-cta { left: 62%; top: 62%; --cp-hx: 18px; --cp-hy: -22px; --cp-lx: 14px; --cp-ly: -24px; }
.cp .cp-hint-logo { left: 50%; top: 60%; --cp-hx: 18px; --cp-hy: -22px; --cp-lx: 14px; --cp-ly: -24px; }
.cp-card .cp-hint-logo { --cp-hx: -26px; --cp-hy: 18px; --cp-lx: -22px; --cp-ly: 22px; } /* on the top line at the right edge: from the left */
.cp .cp-hint-name { left: 34px; top: 13px; }

/* glow (the owner's favourite): a rainbow halo turns behind the photo, a blurred copy of it glows */
.m-glow .cp-slot::before, .m-glow .cp-slot::after { content: ""; position: absolute; inset: 1px; border-radius: 50%; background: conic-gradient(#ff6b6b, #ffb86b, #7c5cff, #2bd4c5, #ff6b6b); animation: spin 4.8s linear infinite; }
.m-glow .cp-slot::after { filter: blur(8px); opacity: .6; }
.m-glow .ph { box-shadow: 0 0 0 3px #fff; }

/* orbs: three soft orbs in the brand's colours circle the photo – the accent, a lighter and a darker shade of it; close enough
   that their blur fades out inside the GIF's frame (designs.js FRAME_FADE) */
.m-orbs .cp-orb { position: absolute; inset: -4px; animation: spin 4.8s linear infinite; pointer-events: none; }
.m-orbs .cp-orb:nth-child(2) { animation-direction: reverse; }
.m-orbs .cp-orb:nth-child(3) { animation-duration: 2.4s; }
.m-orbs .cp-orb::before { content: ""; position: absolute; top: 0; left: 50%; width: 20px; height: 20px; margin-left: -10px; border-radius: 50%; background: var(--acc); filter: blur(5px); }
.m-orbs .cp-orb:nth-child(2)::before { top: auto; bottom: 2px; width: 17px; height: 17px; margin-left: -8.5px; background: color-mix(in srgb, var(--acc) 45%, #fff); }
.m-orbs .cp-orb:nth-child(3)::before { top: 30px; left: 2px; margin-left: 0; width: 14px; height: 14px; background: color-mix(in srgb, var(--acc) 70%, #000); }
.m-orbs .ph { box-shadow: 0 0 0 3px #fff; position: relative; z-index: 1; }

/* ring: the company's name turns slowly round the photo – a third, half or whole turn per loop (designs.js ringOf) */
.m-ring .cp-ringtext { position: absolute; left: -10px; top: -10px; width: 84px; height: 84px; overflow: visible; animation: cp-turn 4.8s linear infinite; }
.m-ring .cp-ringtext text { font: 600 7px "Geist", Arial, sans-serif; letter-spacing: 1.4px; fill: var(--acc); }
@keyframes cp-turn { to { rotate: var(--cp-turn, 360deg); } }

/* holo: the name shimmers in iridescent colours; the gradient travels exactly its own width per loop (seamless) */
.m-holo .nm { width: fit-content; max-width: 100%; padding: .15em 0; margin: -.15em 0; background: linear-gradient(90deg, #8b5cf6, #ec4899, #06b6d4, #f59e0b, #8b5cf6) 0 0 / 200% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; animation: holo 4.8s linear infinite; }
@keyframes holo { to { background-position: 200% 0; } } /* the image is 200 % of the name: 200 % moves it one whole tile, where the repeat starts again */

/* logo: the logo is drawn in from the left once per loop (whole in the first frame); without a logo beside the details,
   what is in the photo slot (the logo as a mark, the photo or the initials) */
.m-logo .bm, .m-logo:not(:has(.bm)) .cp-slot > .ph { animation: cp-draw 4.8s linear infinite; }
@keyframes cp-draw {
  0%, 56% { clip-path: inset(0 0 0 0); opacity: 1; }
  60% { clip-path: inset(0 0 0 0); opacity: 0; }
  60.5% { clip-path: inset(0 100% 0 0); opacity: 0; }
  61% { clip-path: inset(0 100% 0 0); opacity: 1; animation-timing-function: cubic-bezier(.55, 0, .25, 1); }
  84%, 100% { clip-path: inset(0 0 0 0); opacity: 1; }
}

/* badge: the logo in a white disc on the photo's lower right corner, half out of the photo, ringed in white over it,
   with a soft shadow; the logo fills the disc (3 px inside it: a tall crest fits the circle whole; a square logo's corners are clipped to it); the disc beats (fx heartbeat, designs.js MOTIONS), the photo stays still. The disc is the logo
   part, so the chat moves it (right, bottom…), resizes it (width and height) and gives it other animations. */
.m-badge .cp-badge { position: absolute; right: -7px; bottom: -2px; z-index: 2; width: 28px; height: 28px; box-sizing: border-box; padding: 3px; border-radius: 50%;
  overflow: hidden; background: #fff; display: grid; place-items: center; box-shadow: 0 0 0 2px #fff, 0 2px 6px rgba(0, 0, 0, .28); }
.m-badge .cp-badge-logo { display: block; width: 100%; height: 100%; object-fit: contain; }
