/*
Theme Name: Viis
Theme URI: https://getviis.com
Author: KKG Consulting
Author URI: https://kkgconsulting.fi
Description: Landing theme for Viis — a WhatsApp assistant for accounting systems. Paper, ink and one ochre; IBM Plex Sans and Mono. Classic PHP theme, no build step.
Version: 5.0.1
Requires at least: 6.4
Requires PHP: 8.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: vis
Tags: one-column, custom-menu, custom-logo, editor-style
*/

:root{
  /* Viis Studio's light theme, adopted whole (apps/studio/assets/tokens.css).
     The variable names are the old ones on purpose: every rule in this file
     already reads them, so the palette moves in one place and the change is
     one commit to revert. Cream, warm hairlines and the ochre are retired;
     Studio dropped them as reading archival, and the site kept wearing them. */
  --vis-ink:#18181a;          /* text            */
  --vis-paper:#fafafa;        /* surface base    */
  --vis-white:#ffffff;        /* raised, cards   */
  --vis-sand:#f6f6f5;         /* sunken bands    */
  --vis-ochre:#f5b014;        /* accent: "act"   */
  --vis-ochre-deep:#e0a00c;
  --vis-ochre-text:#a0730a;
  --vis-muted:#5c5c5f;
  --vis-body:#46464a;
  --vis-rule:#efefed;
  --vis-hairline:#e6e6e4;
  --vis-ink-muted:#a3a3a3;    /* on the dark band */
  --vis-ink-dim:#8f8f92;
  --vis-dark:#151515;         /* the one dark surface */
  --vis-dark-raised:#1c1c1c;

  /* Shape and motion, from the same token set. */
  --vis-r-sm:4px;
  --vis-r-md:6px;
  --vis-r-lg:8px;
  --vis-shadow:0 1px 2px rgb(0 0 0 / 0.04), 0 4px 12px -6px rgb(0 0 0 / 0.06);
  --vis-dur:180ms;
  --vis-ease:cubic-bezier(0.16,1,0.3,1);
  --vis-chat-green:#CFE6CE;
  --vis-chat-green-ink:#16261A;
  --vis-sans:'IBM Plex Sans',system-ui,-apple-system,'Segoe UI',sans-serif;
  --vis-mono:'IBM Plex Mono',ui-monospace,'SFMono-Regular',Menlo,monospace;
  --vis-max:1240px;
  --vis-pad:40px;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--vis-paper);color:var(--vis-ink);font-family:var(--vis-sans);font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased}
img,svg{max-width:100%;display:block}
a{color:var(--vis-ink)}
@media (prefers-reduced-motion:no-preference){
  a,button,.vis-tier,.vis-step{transition:color var(--vis-dur) var(--vis-ease),background-color var(--vis-dur) var(--vis-ease),border-color var(--vis-dur) var(--vis-ease)}
}
a:hover{color:var(--vis-ochre-text)}
::selection{background:var(--vis-ochre);color:var(--vis-ink)}
h1,h2,h3{margin:0;letter-spacing:-0.025em;text-wrap:pretty}
p{margin:0;text-wrap:pretty}
.vis-skip{position:absolute;left:-9999px}
.vis-skip:focus{left:12px;top:12px;z-index:99;background:var(--vis-ink);color:var(--vis-paper);padding:10px 14px}
.vis-wrap{max-width:var(--vis-max);margin:0 auto;padding-left:var(--vis-pad);padding-right:var(--vis-pad)}
.vis-mono{font-family:var(--vis-mono)}
.vis-eyebrow{font-size:12.5px;line-height:1;font-weight:500;color:var(--vis-muted)}
.vis-label{font-size:13px;line-height:1;font-weight:500;color:var(--vis-ink)}
.vis-num{font-family:var(--vis-mono);font-size:11.5px;font-weight:500;line-height:1;letter-spacing:0.12em;color:var(--vis-ochre-text)}

/* ---- buttons ---- */
.vis-btn{display:inline-flex;align-items:center;height:40px;padding:0 18px;text-decoration:none;font-weight:600;font-size:14.5px;line-height:1;white-space:nowrap;border:none;cursor:pointer;font-family:var(--vis-sans);border-radius:var(--vis-r-md);transition:background var(--vis-dur) var(--vis-ease),border-color var(--vis-dur) var(--vis-ease),color var(--vis-dur) var(--vis-ease)}
.vis-btn--primary{background:var(--vis-ochre);color:var(--vis-ink)}
.vis-btn--primary:hover{background:var(--vis-ochre-deep);color:var(--vis-ink)}
.vis-btn--ghost{border:1px solid var(--vis-hairline);color:var(--vis-ink);font-weight:500;background:var(--vis-white)}
.vis-btn--ghost:hover{background:var(--vis-white);border-color:var(--vis-ochre);color:var(--vis-ink)}
.vis-btn--ghost-dark{border:1px solid #4A443A;color:var(--vis-paper);font-weight:500}
.vis-btn--ghost-dark:hover{border-color:var(--vis-ochre);color:var(--vis-paper)}
/* Header-only. Its height sets the height of the bar, so it is the first thing
   to trim when the bar needs to be thinner. 34px still clears the 24px minimum
   target size comfortably, including as the sole nav control on phones. */
.vis-btn--sm{height:32px;padding:0 14px;font-size:13px;font-weight:500;background:var(--vis-ink);color:#ffffff}
.vis-btn--sm:hover{background:var(--vis-ochre);color:var(--vis-ink)}
.vis-btn-row{display:flex;gap:12px;flex-wrap:wrap;padding-top:6px}

/* ---- header ---- */
.vis-header{border-bottom:1px solid var(--vis-hairline);background:rgba(250,250,250,.86);backdrop-filter:saturate(180%) blur(12px);position:sticky;top:0;z-index:40}
.vis-header__inner{display:flex;align-items:center;gap:30px;padding-top:11px;padding-bottom:11px}
.vis-brand{display:flex;align-items:center;gap:9px;text-decoration:none}
/* If a custom logo is ever set in the Customizer, the_custom_logo() renders it
   at whatever size it was uploaded and the bar's height stops being the theme's
   decision. Cap it to the mark's height so a thin header survives that. */
.vis-brand img{height:26px;width:auto}
.vis-brand__word{font-family:var(--vis-mono);font-weight:600;font-size:19px;line-height:1;letter-spacing:0.04em;color:var(--vis-ink)}
.vis-nav{display:flex;gap:24px;margin-left:auto;align-items:center;flex-wrap:wrap}
.vis-nav a{font-size:13.5px;text-decoration:none;line-height:1;color:var(--vis-muted);transition:color var(--vis-dur) var(--vis-ease)}
.vis-nav a:hover{color:var(--vis-ink)}
.vis-nav a.vis-btn--sm{color:#ffffff}
.vis-login{margin-left:4px;padding-left:22px;border-left:1px solid var(--vis-hairline)}
/* Language switcher. Deliberately quiet: it is wayfinding, not a call to
   action, so it reads as a pair of small mono labels with the current one
   inked and the other dimmed. */
.vis-login{font-size:13.5px;text-decoration:none;color:var(--vis-muted)}
.vis-lang{display:inline-flex;align-items:center;gap:8px;font-family:var(--vis-mono, 'IBM Plex Mono', monospace);font-size:11.5px;letter-spacing:0.08em;font-weight:500}
.vis-lang a{font-size:inherit;color:var(--vis-ink-dim);text-decoration:none;padding:2px 0}
.vis-lang a:hover,.vis-lang a:focus-visible{color:var(--vis-ink)}
.vis-lang a.is-current{color:var(--vis-ink);text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:1.5px;text-decoration-color:var(--vis-ochre)}
.vis-lang a+a{border-left:1px solid var(--vis-hairline);padding-left:8px}

/* ---- hero ---- */
/* overflow: the dark demo panel bleeds past the right edge; clip it here so it
   never adds horizontal scroll. */
.vis-hero{border-bottom:1px solid var(--vis-ink);overflow:hidden}
.vis-hero__inner{--vis-hero-pt:52px;--vis-hero-pb:64px;--vis-hero-gap:56px;display:flex;flex-direction:column;align-items:center;text-align:center;width:100%;padding-top:var(--vis-hero-pt);padding-bottom:var(--vis-hero-pb);gap:0}
.vis-hero__copy{display:flex;flex-direction:column;align-items:center;gap:16px;max-width:640px;margin-bottom:34px}
.vis-hero__copy>*{margin-block:0}
.vis-hero__copy>.vis-btn-row{padding-top:2px}
.vis-hero__copy>.vis-features{margin-top:6px}
.vis-hero h1{font-size:50px;line-height:1.06;letter-spacing:-0.034em;font-weight:600;max-width:16ch}
.vis-hero__sub{max-width:52ch;font-size:17.5px;line-height:1.62;color:var(--vis-body)}

/* ---- chat mockup: WhatsApp-style interface ----
   A stylised likeness of the messenger UI. No WhatsApp logo or wordmark is
   used; the avatar is the Viis mark. */
/* Width, not height, sets the proportions here: the height is spoken for by the
   fold, so a phone-shaped device has to be narrow. At 316px the screen comes
   out 294x627 — about 1:2.13, where a current handset is 1:2.16. It was 1:1.73,
   which is why it read as a slab. Bezel, corner radius and the island are cut
   to match; they would look oversized at this width otherwise. */
.vis-phone{width:316px;flex:none;position:relative;background:#0B0B0B;padding:11px;border-radius:46px;box-shadow:0 0 0 1px #35322B inset,0 30px 70px -24px rgba(22,21,15,.55)}
.vis-phone::before{content:'';position:absolute;top:20px;left:50%;transform:translateX(-50%);width:86px;height:24px;border-radius:13px;background:#0B0B0B;z-index:2}
.vis-wa{background:#ECE5DD;border-radius:36px;overflow:hidden;display:flex;flex-direction:column;text-align:left}
/* Light bar, as the current app has it — the teal header is the older look.
   The green survives as the tint on the bar's controls and the send button. */
.vis-wa__bar{display:flex;align-items:center;gap:9px;background:#F6F6F6;color:#111B21;padding:39px 13px 10px;border-bottom:1px solid #E4E4E4}
.vis-wa__back{font-size:22px;line-height:1;color:#00A884}
.vis-wa__avatar{width:30px;height:30px;border-radius:50%;background:var(--vis-ochre);display:flex;align-items:center;justify-content:center;flex:none;overflow:hidden}
.vis-wa__who{display:flex;flex-direction:column;line-height:1.25;flex:1;min-width:0}
.vis-wa__name{font-size:14px;font-weight:600;color:#111B21}
.vis-wa__status{font-size:11px;color:#667781}
.vis-wa__icons{display:flex;align-items:center;gap:15px;font-size:16px;color:#00A884}
.vis-wa__icons svg{display:block;fill:currentColor}
.vis-wa__input{display:flex;align-items:center;gap:8px;background:#ECE5DD;padding:8px 12px 26px}
/* The pill is the wrapper now, so the emoji, attach and camera glyphs can sit
   inside it as the real composer does. They are set dressing: aria-hidden and
   pointer-events:none, so they are never mistaken for controls that work. */
.vis-wa__composer{flex:1;min-width:0;display:flex;align-items:center;gap:9px;background:#fff;border-radius:20px;padding:0 12px}
/* WhatsApp's order: + outside the pill, sticker inside it, then camera and mic
   — which the real client swaps for a send button the moment you type. The
   send button is the only control here that does anything, so it earns its
   place by appearing exactly when it is useful. */
.vis-wa__idle{display:flex;align-items:center;gap:14px;flex:none}
.vis-wa__input.is-typing .vis-wa__idle{display:none}
.vis-wa__input:not(.is-typing) .vis-wa__send{display:none}
.vis-wa__composer:focus-within{outline:2px solid var(--vis-ochre);outline-offset:1px}
.vis-wa__ico{flex:none;fill:#54656F;pointer-events:none}
.vis-wa__field{flex:1;min-width:0;background:none;border:none;padding:11px 0;font-size:13.5px;color:#111B21;font-family:var(--vis-sans)}
.vis-wa__field::placeholder{color:#9A9285}
.vis-wa__field:disabled{cursor:default}
.vis-wa__field:focus{outline:none}
.vis-wa__send{width:38px;height:38px;flex:none;border:none;border-radius:50%;background:#00A884;color:#fff;display:flex;align-items:center;justify-content:center;font-size:14px;cursor:pointer;padding:0}
.vis-wa__send:hover{background:#008F70}
.is-live .vis-wa__composer{box-shadow:0 0 0 1px #D7D2C6}
/* the message stream, on the messenger's wallpaper */
.vis-chat{background-color:#ECE5DD;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='90' viewBox='0 0 90 90'%3E%3Cg fill='none' stroke='%23D9D0C2' stroke-width='1.1' stroke-linecap='round' opacity='.55'%3E%3Ccircle cx='16' cy='18' r='5'/%3E%3Cpath d='M56 12h14v10H62l-3 4v-4h-3z'/%3E%3Cpath d='M30 52l4 4 8-9'/%3E%3Crect x='60' y='54' width='13' height='16' rx='2'/%3E%3Cpath d='M12 74h12M12 79h8'/%3E%3Cpath d='M74 30l5 5-5 5-5-5z'/%3E%3C/g%3E%3C/svg%3E");padding:14px 12px 6px;display:flex;flex-direction:column;gap:7px;height:470px;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.vis-chat::-webkit-scrollbar{display:none}
.vis-flow{display:none;flex-direction:column;gap:7px;margin-top:auto}
.vis-flow.is-active{display:flex}
.vis-flow:first-child{display:flex}  /* no-JS: show the first conversation */
.vis-msg{max-width:88%;padding:7px 9px 6px;font-size:13.5px;line-height:1.45;border-radius:8px;box-shadow:0 1px 0.5px rgba(11,20,26,.13);position:relative;white-space:pre-wrap;word-break:break-word}
.vis-msg strong{font-weight:600}
.vis-msg em{font-style:italic}
.vis-msg code{font-family:var(--vis-mono);font-size:12px;background:#F0F2F5;border-radius:3px;padding:0 3px}
.vis-msg ul{margin:5px 0 7px;padding-left:16px;list-style:none;white-space:normal}
.vis-msg ul:last-child{margin-bottom:0}
.vis-msg li{position:relative;margin:2px 0;line-height:1.45}
.vis-msg li::before{content:'\2022';position:absolute;left:-12px;color:#667781}
/* Tails. The messenger draws a pointed tail on the first bubble of a run and
   squares off that corner; a rounded corner alone is the clearest tell that a
   chat mockup is not the real thing. Absolutely positioned, so it stays out of
   the incoming bubble's flex flow. The 8px reach fits inside .vis-chat's 12px
   side padding, so it is never clipped. */
.vis-msg--out{align-self:flex-end;background:#DCF8C6;color:#111B21;border-top-right-radius:0}
.vis-msg--out::after{content:'';position:absolute;top:0;right:-8px;width:8px;height:13px;background:#DCF8C6;clip-path:polygon(0 0,0 100%,100% 0)}
.vis-msg--in{align-self:flex-start;background:#fff;color:#111B21;border-top-left-radius:0;display:flex;flex-direction:column;gap:6px}
.vis-msg--in::before{content:'';position:absolute;top:0;left:-8px;width:8px;height:13px;background:#fff;clip-path:polygon(100% 0,100% 100%,0 0)}
.vis-msg__time{display:block;text-align:right;font-size:10.5px;line-height:1;color:#667781;margin-top:3px;white-space:nowrap}
/* Outgoing bubbles are plain blocks, so the timestamp can sit on the last line
   of text the way the real client does. Incoming ones are flex columns holding
   ledgers and action rows, where a float would not apply. */
.vis-msg--out .vis-msg__time{float:right;margin:3px 0 0 12px}
.vis-tick{margin-left:3px;color:#53BDEB;letter-spacing:-2px}
.vis-msg__ledger{font-family:var(--vis-mono);font-size:11.5px;line-height:1.65;color:#3A342A;background:#F3F1E9;border-left:3px solid var(--vis-ochre);padding:7px 9px;white-space:nowrap;overflow-x:auto;scrollbar-width:none}
.vis-msg__log{font-family:var(--vis-mono);font-size:11px;line-height:1.4;color:var(--vis-ochre-text)}
.vis-msg__actions{display:flex;flex-direction:column;gap:0;margin:8px -9px -6px;border-top:1px solid #E4E6E8}
.vis-msg__btn{display:flex;align-items:center;justify-content:center;gap:6px;width:100%;padding:11px 0;font-size:13.5px;line-height:1;font-weight:500;border:none;background:none;color:#027EB5;cursor:pointer;font-family:inherit}
.vis-msg__btn+.vis-msg__btn{border-top:1px solid #E4E6E8}
.vis-msg__btn::before{content:'\21A9';font-size:12px;opacity:.85}
.vis-msg__btn:hover{background:#F5F6F6}


/* ---- sections ---- */
.vis-section{border-bottom:1px solid var(--vis-ink)}
.vis-section--sand{background:var(--vis-sand)}
.vis-section--ink{background:var(--vis-dark);color:#ededed;border-bottom:none}
.vis-section__inner{padding-top:56px;padding-bottom:60px}
/* Stacked, not space-between: with a short lede the old rule flung it to the
   far right edge, where it read as unrelated to the heading it belongs to. */
.vis-section__head{display:flex;flex-direction:column;align-items:flex-start;gap:12px;margin-bottom:40px}
.vis-section__head h2{font-size:29px;line-height:1.18;letter-spacing:-0.024em;font-weight:600;max-width:22ch}
.vis-section__lede{max-width:42ch;font-size:15.5px;line-height:1.6;color:var(--vis-muted)}

/* ---- safeguards ---- */
.vis-grid-6{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--vis-rule);border:1px solid var(--vis-rule)}
.vis-card{background:var(--vis-white);padding:30px 28px;display:flex;flex-direction:column;gap:12px}
.vis-card h3{font-size:18px;line-height:1.3;letter-spacing:-0.014em;font-weight:600}
.vis-card p{font-size:14.5px;line-height:1.6;color:var(--vis-body)}

/* ---- accountants ---- */
.vis-split{display:flex;gap:64px;align-items:flex-start;flex-wrap:wrap;padding-top:76px;padding-bottom:84px}
.vis-split__copy{flex:1;min-width:380px;display:flex;flex-direction:column;gap:24px}
.vis-split__copy h2{font-size:38px;line-height:1.12;letter-spacing:-0.028em;font-weight:600;max-width:22ch}
.vis-split__copy p{max-width:46ch;font-size:16.5px;line-height:1.62;color:#C4BCA9}
.vis-queue{width:440px;flex:none;background:var(--vis-paper);color:var(--vis-ink)}
.vis-queue__head{display:flex;align-items:center;justify-content:space-between;padding:14px 20px;border-bottom:1px solid var(--vis-ink)}
.vis-queue__row{padding:16px 20px;border-bottom:1px solid var(--vis-rule);border-left:3px solid var(--vis-ochre);display:flex;flex-direction:column;gap:6px}
.vis-queue__row--quiet{border-left-color:var(--vis-rule)}
.vis-queue__row--quiet .vis-queue__title{color:var(--vis-muted)}
.vis-queue__title{display:flex;justify-content:space-between;gap:16px;font-size:13.5px;font-weight:500;line-height:1.4}
.vis-queue__amount{font-family:var(--vis-mono);font-size:13px;font-weight:400;white-space:nowrap}
.vis-queue__meta{font-family:var(--vis-mono);font-size:12px;line-height:1.5;color:var(--vis-muted)}
.vis-queue__foot{padding:16px 20px;display:flex;align-items:center;justify-content:space-between;gap:16px;background:var(--vis-sand);font-family:var(--vis-mono);font-size:12px;line-height:1.5;color:var(--vis-muted)}
.vis-queue__foot span:last-child{color:var(--vis-ochre-text);font-weight:500}

/* ---- steps ---- */
/* One panel divided by hairlines rather than three boxes floating apart — the
   same idiom as .vis-strip__grid, and it stops three heavy ink borders from
   competing with the section's own rule. */
.vis-steps{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.vis-step{min-width:0;background:var(--vis-white);border:1px solid var(--vis-hairline);border-radius:var(--vis-r-lg);padding:24px 24px 26px;display:flex;flex-direction:column;gap:10px}
.vis-step:hover{border-color:#d4d4d1}
.vis-step__num+h3{margin-top:2px}
.vis-step__num{font-size:13px;font-weight:600;line-height:1;color:var(--vis-ochre-text)}
.vis-step h3{font-size:22px;line-height:1.25;letter-spacing:-0.018em;font-weight:600}
.vis-step p{font-size:15px;line-height:1.6;color:var(--vis-body)}

/* ---- limits strip ---- */
.vis-strip{padding-top:60px;padding-bottom:66px}
.vis-strip__grid{display:flex;gap:1px;background:#33302A;flex-wrap:wrap}
.vis-strip__item{flex:1;min-width:260px;background:var(--vis-ink);padding:26px 30px}
.vis-strip__item:first-child{padding-left:0}
.vis-strip__item:last-child{padding-right:0}
.vis-strip__item h3{font-size:19px;line-height:1.3;letter-spacing:-0.016em;font-weight:600;margin-bottom:10px}
.vis-strip__item p{font-size:15px;line-height:1.6;color:var(--vis-ink-muted)}

/* ---- proof ---- */
.vis-proof{display:flex;gap:56px;align-items:flex-start;flex-wrap:wrap;padding-top:64px;padding-bottom:70px}
.vis-proof h2{flex:none;width:280px;font-size:28px;line-height:1.2;letter-spacing:-0.022em;font-weight:600}
.vis-proof__list{flex:1;min-width:420px;display:flex;flex-direction:column;gap:20px}
.vis-proof__item{display:flex;gap:18px;align-items:flex-start}
.vis-proof__item:not(:last-child){border-bottom:1px dashed var(--vis-rule);padding-bottom:20px}
.vis-proof__item p{font-size:16.5px;line-height:1.6;color:#3A342A}
.vis-proof__item .vis-num{flex:none;width:28px;line-height:1.6}

/* ---- pilot form ---- */
.vis-pilot{display:flex;gap:64px;align-items:flex-start;flex-wrap:wrap;padding-top:72px;padding-bottom:84px}
.vis-pilot__copy{flex:1;min-width:400px;display:flex;flex-direction:column;gap:20px}
.vis-pilot__copy h2{font-size:34px;line-height:1.15;letter-spacing:-0.026em;font-weight:600;max-width:20ch}
.vis-pilot__copy p{max-width:44ch;font-size:16.5px;line-height:1.62;color:var(--vis-body)}
/* On the ink ground the body colour would be near-invisible, and the form's
   ink border disappears into it; the paper panel carries its own edge. */
.vis-section--ink .vis-pilot__copy p{color:var(--vis-ink-muted)}
.vis-section--ink .vis-form{border-color:transparent}
.vis-pilot__note{font-family:var(--vis-mono);font-size:12.5px;line-height:1.7;color:var(--vis-muted);border-top:1px dashed var(--vis-hairline);padding-top:18px}
.vis-form{flex:1;min-width:460px;background:var(--vis-paper);border:1px solid var(--vis-ink);padding:32px;display:flex;flex-direction:column;gap:20px}
.vis-field{display:flex;flex-direction:column;gap:8px}
.vis-field input,.vis-field select{font-family:var(--vis-sans);font-size:15px;line-height:1.4;color:var(--vis-ink);background:var(--vis-white);border:1px solid var(--vis-hairline);padding:10px 13px;width:100%;border-radius:var(--vis-r-md);-webkit-appearance:none;appearance:none}
/* Room for the arrow drawn at 14-20px from the right edge; without it a
   long option label runs underneath the chevron. */
.vis-field select{padding-right:40px;text-overflow:ellipsis}
.vis-field select{background-image:linear-gradient(45deg,transparent 50%,var(--vis-ink) 50%),linear-gradient(135deg,var(--vis-ink) 50%,transparent 50%);background-position:calc(100% - 20px) 20px,calc(100% - 14px) 20px;background-size:6px 6px,6px 6px;background-repeat:no-repeat}
.vis-field input:focus,.vis-field select:focus{border-color:var(--vis-ochre);outline:2px solid var(--vis-ochre);outline-offset:-2px}
.vis-form__fine{font-size:12.5px;line-height:1.6;color:var(--vis-muted)}
.vis-form__fine a{text-decoration:underline}
.vis-hp{position:absolute;left:-9999px}
.vis-field__hint{font-size:12.5px;line-height:1.5;color:var(--vis-muted)}
/* The way out for someone who is not buying yet. Sits above the legal fine
   print and is deliberately more legible than it. */
.vis-form__ask{display:flex;flex-direction:column;align-items:flex-start;gap:10px;font-size:14px;line-height:1.55;color:var(--vis-body);margin:0;padding-top:2px}
/* Secondary on purpose: this is the way out for someone not buying today, and
   it must not compete with Start setup directly above it. */
.vis-wa-btn{display:inline-flex;align-items:center;gap:8px;height:36px;padding:0 14px;border:1px solid var(--vis-hairline);border-radius:var(--vis-r-md);background:var(--vis-white);color:var(--vis-ink);font-size:14px;font-weight:500;text-decoration:none;transition:border-color var(--vis-dur) var(--vis-ease),color var(--vis-dur) var(--vis-ease)}
.vis-wa-btn:hover{border-color:#25D366;color:#128C4A}
.vis-wa-btn svg{color:#25D366;flex:none}
.vis-form__ask a{color:var(--vis-ink);text-decoration:underline;text-underline-offset:2px}
.vis-notice{border-left:3px solid var(--vis-ochre);background:var(--vis-white);border-radius:var(--vis-r-md);padding:14px 16px;font-size:14.5px;line-height:1.55}
.vis-notice--error{border-left-color:#8C3A1E}

/* ---- footer ---- */
.vis-footer{background:var(--vis-ink);color:var(--vis-ink-muted)}
.vis-footer__inner{padding-top:48px;padding-bottom:56px;display:flex;gap:56px;justify-content:space-between;flex-wrap:wrap}
.vis-footer__cols{display:flex;gap:56px;flex-wrap:wrap}
.vis-footer__col{display:flex;flex-direction:column;gap:10px;max-width:32ch}
.vis-footer__col a{font-size:13.5px;line-height:1.5;color:var(--vis-ink-muted);text-decoration:none}
.vis-footer__col a:hover{color:var(--vis-ochre)}
.vis-footer__label{font-size:12px;line-height:1;font-weight:500;color:var(--vis-ink-dim)}
.vis-footer__brand{display:flex;flex-direction:column;gap:14px}
.vis-footer__word{font-family:var(--vis-mono);font-weight:600;font-size:20px;line-height:1;letter-spacing:0.04em;color:var(--vis-paper)}
.vis-footer__addr{font-size:13px;line-height:1.7}
.vis-footer__legal{font-size:12.5px;line-height:1.6;color:var(--vis-ink-muted)}

/* ---- page / privacy ---- */
.vis-page{padding-top:64px;padding-bottom:80px;max-width:760px}
.vis-page h1{font-size:40px;line-height:1.12;font-weight:600;margin-bottom:24px}
.vis-page h2{font-size:22px;line-height:1.3;font-weight:600;margin:36px 0 12px}
.vis-page p,.vis-page li{font-size:16px;line-height:1.65;color:var(--vis-body)}
.vis-page ul{padding-left:20px}
.vis-page table{width:100%;border-collapse:collapse;margin:20px 0;font-size:14px}
.vis-page th,.vis-page td{text-align:left;border-bottom:1px solid var(--vis-rule);padding:10px 12px}
.vis-page th{font-size:12.5px;font-weight:600;color:var(--vis-muted)}

@media (max-width:1080px){
  .vis-grid-6{grid-template-columns:repeat(2,1fr)}
  .vis-queue{width:100%}
}
@media (max-width:860px){
  :root{--vis-pad:24px}
  .vis-hero__inner{flex-direction:column;align-items:stretch;padding-top:48px}
  .vis-hero__copy{padding-bottom:32px;min-width:0}
  .vis-feature .vis-step__num{width:64px}
  .vis-feature__body{padding-left:78px}
  .vis-hero h1{font-size:38px}
  .vis-phone{width:100%;max-width:316px;margin:0 auto}
  .vis-section__inner,.vis-split,.vis-pilot,.vis-proof{padding-top:52px;padding-bottom:56px}
  .vis-section__head h2,.vis-pilot__copy h2{font-size:28px}
  .vis-split__copy,.vis-split__copy h2{min-width:0}
  .vis-split__copy h2{font-size:30px}
  .vis-grid-6{grid-template-columns:1fr}
  .vis-steps{grid-template-columns:1fr}
  .vis-tiers{grid-template-columns:1fr;margin-top:28px}
  .vis-facts{grid-template-columns:1fr}
  .vis-status{grid-template-columns:1fr;gap:8px}
  /* Stack explicitly. min-width:0 below lets these shrink, which is what a
     narrow screen needs — but shrinking is also what stops the row ever
     wrapping, so relying on flex-wrap left two 50% columns on a phone. */
  .vis-split,.vis-proof,.vis-pilot{flex-direction:column;align-items:stretch;gap:32px}
  .vis-form,.vis-proof__list,.vis-pilot__copy{min-width:0}
  .vis-proof h2{width:100%}
  .vis-strip__item{padding:22px 0}
  .vis-nav{gap:16px}
  .vis-nav a:not(.vis-btn--sm){display:none}
  /* ...except the language switcher, which a Finnish reader on a phone needs
     more than anyone. Re-shown by specificity rather than a :not() with a
     combinator, which older iOS Safari does not parse. */
  .vis-nav .vis-lang a{display:inline-block}
  /* Log in survives the mobile rule too: a customer reaching for it on a
     phone is the whole point of shipping a hosted product. */
  .vis-nav a.vis-login{display:inline-block;font-size:13px;border-bottom:none}
  .vis-lang{gap:6px;font-size:11px}
  .vis-lang a+a{padding-left:6px}
}

/* Core gives blocks their own vertical margins; our containers space their
   children with flex gap, so the two stack up into oversized gaps. */
.vis-hero__copy>*,.vis-split__copy>*,.vis-pilot__copy>*,.vis-section__head>*,
.vis-card>*,.vis-step>*,.vis-strip__item>*,.vis-proof__item>*,.vis-qa__item>*,
.vis-bridge>*,.vis-pricing__intro>*{margin-block:0}

/* ---- block-editor shims ----
   The landing page is Gutenberg content: core wraps everything in
   .wp-block-group and adds its own margins. These keep the composed layout
   identical to the original template parts. */
.wp-block-group.vis-hero__inner,
.wp-block-group.vis-split,
.wp-block-group.vis-pilot,
.wp-block-group.vis-proof,
.wp-block-group.vis-section__inner,
.wp-block-group.vis-strip{margin-top:0;margin-bottom:0}
.vis-section>.wp-block-group,
.vis-hero>.wp-block-group{margin-top:0;margin-bottom:0}
.wp-block-group.vis-card,
.wp-block-group.vis-step,
.wp-block-group.vis-strip__item,
.wp-block-group.vis-proof__item,
.wp-block-group.vis-hero__copy,
.wp-block-group.vis-split__copy,
.wp-block-group.vis-pilot__copy,
.wp-block-group.vis-section__head,
.wp-block-group.vis-grid-6,
.wp-block-group.vis-steps,
.wp-block-group.vis-strip__grid,
.wp-block-group.vis-proof__list,
.wp-block-group.vis-pricing__intro{margin-block:0}
/* The shim above zeroes this element's margins at a specificity the base rule
   cannot beat, so the section head's 40px of air has never actually applied —
   headings have been sitting on top of the content below them. Restored here,
   after the shim, where it sticks. */
.wp-block-group.vis-section__head{margin-bottom:30px}
.wp-block-group.vis-pricing__intro{margin-bottom:0}
.vis-eyebrow--dim{color:var(--vis-ink-dim)}
.vis-strip__eyebrow{margin-bottom:30px}
.vis-btn--block{height:40px;justify-content:center}
/* Editor: give blocks the page's paper ground so contrast reads true. */
.editor-styles-wrapper{background:var(--vis-paper)}

/* ---- three-up grid (waitlist) ---- */
.vis-grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--vis-rule);border:1px solid var(--vis-rule)}
.vis-tag{display:inline-block;align-self:flex-start;font-family:var(--vis-mono);font-size:11px;line-height:1;letter-spacing:0.12em;padding:6px 9px;background:var(--vis-ink);color:var(--vis-paper)}
.vis-btn-row--center{justify-content:center;padding-top:36px}
.wp-block-group.vis-grid-3{margin-block:0}
@media (max-width:860px){.vis-grid-3{grid-template-columns:1fr}}

/* ---- Q&A (for accountants) ---- */
.vis-qa{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--vis-rule);border:1px solid var(--vis-rule)}
.vis-qa__item{background:var(--vis-white);padding:28px 30px}
.vis-qa__item h3{font-size:17px;line-height:1.35;letter-spacing:-0.012em;font-weight:600;margin-bottom:10px}
.vis-qa__item p{font-size:15px;line-height:1.62;color:var(--vis-body)}
.wp-block-group.vis-qa,.wp-block-group.vis-qa__item{margin-block:0}
@media (max-width:860px){.vis-qa{grid-template-columns:1fr}}

/* ---- accountant bridge (front page) ---- */
.vis-bridge{padding-top:64px;padding-bottom:70px;display:flex;flex-direction:column;gap:18px;align-items:flex-start}
.vis-bridge h2{font-size:32px;line-height:1.15;letter-spacing:-0.026em;font-weight:600;max-width:22ch}
.vis-bridge p{max-width:52ch;font-size:16.5px;line-height:1.62;color:#C4BCA9}
.wp-block-group.vis-bridge{margin-block:0}

/* ---- two-up grid (waitlist) ---- */
.vis-grid-2{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--vis-rule);border:1px solid var(--vis-rule)}
.wp-block-group.vis-grid-2{margin-block:0}
@media (max-width:860px){.vis-grid-2{grid-template-columns:1fr}}

/* ---- chat ---- */
.vis-chat .vis-msg{animation:vis-pop .22s ease-out}
@keyframes vis-pop{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.vis-typing{align-self:flex-start;position:relative;display:flex;gap:4px;align-items:center;background:#fff;border-radius:8px;border-top-left-radius:0;box-shadow:0 1px 0.5px rgba(11,20,26,.13);padding:12px 14px}
.vis-typing::before{content:'';position:absolute;top:0;left:-8px;width:8px;height:13px;background:#fff;clip-path:polygon(100% 0,100% 100%,0 0)}
.vis-typing span{width:5px;height:5px;border-radius:50%;background:#9AA4A8;animation:vis-blink 1.2s infinite}
.vis-typing span:nth-child(2){animation-delay:.2s}
.vis-typing span:nth-child(3){animation-delay:.4s}
@keyframes vis-blink{0%,60%,100%{opacity:.25}30%{opacity:1}}
@media (prefers-reduced-motion:reduce){
  .vis-chat .vis-msg{animation:none}
  .vis-typing span{animation:none}
}

/* ---- interactive demo ---- */
.vis-features{display:flex;flex-direction:column;gap:1px;background:var(--vis-rule);border-top:1px solid var(--vis-rule);border-bottom:1px solid var(--vis-rule)}
.vis-feature{display:flex;flex-wrap:wrap;align-items:baseline;gap:0 14px;width:100%;text-align:left;background:var(--vis-paper);border:none;cursor:pointer;padding:14px 16px;font-family:inherit;border-left:3px solid transparent;transition:background .15s,border-color .15s}
.vis-feature:hover{background:#EDE8DC}
.vis-feature.is-active{background:var(--vis-white);border-left-color:var(--vis-ochre)}
.vis-feature .vis-step__num{flex:none;width:74px;margin:0}
.vis-feature__head{flex:1;font-size:16px;line-height:1.3;font-weight:600;letter-spacing:-0.012em;color:var(--vis-ink)}
/* the description belongs to the selected job only — keeps the list short */
.vis-feature__body{display:none;flex-basis:100%;padding-left:88px;margin-top:6px;font-size:14px;line-height:1.5;color:var(--vis-muted)}
.vis-feature.is-active .vis-feature__body{display:block}
.vis-feature:focus-visible{outline:2px solid var(--vis-ochre);outline-offset:-2px}
/* hero without the phone */
@media (max-width:860px){
  .vis-chat{height:420px}
}

/* ---- demo simulator ---- */
.vis-stage{display:flex;flex-direction:column;align-items:center;gap:16px}
.vis-demo__note{max-width:420px;font-family:var(--vis-mono);font-size:11px;line-height:1.5;color:var(--vis-ink-dim);text-align:center}
.vis-flow--live{margin-top:0}

/* ---- the four jobs, as copy ---- */
.vis-jobs{display:grid;grid-template-columns:repeat(2,1fr);gap:22px 48px;max-width:760px;margin-top:44px;text-align:left}
.vis-job{display:flex;flex-direction:column;gap:5px}
.vis-job__text{font-size:14.5px;line-height:1.55;color:var(--vis-body)}
/* ---- start over ---- */
.vis-reset{align-self:center;margin-top:2px;background:none;border:none;cursor:pointer;font-size:12.5px;color:var(--vis-ink-dim);padding:4px}
.vis-reset:hover{color:var(--vis-ochre-text)}
@media (max-width:860px){
  /* 16px exactly. Safari zooms the whole page when a focused input is smaller
     than this, and once it zooms the fixed panel no longer matches the screen:
     bubbles run past the right edge and the page shows through below. */
  .vis-wa__field{font-size:16px}

  .vis-jobs{grid-template-columns:1fr;gap:18px;margin-top:34px}
  .vis-hero__copy{margin-bottom:26px}

  /* Fullscreen demo. On a phone the mockup's bezel, island and rounded corners
     are set dressing that costs real screen, so they go and the chat takes the
     viewport. dvh, not vh, or the browser's own chrome crops the input row. */
  .vis-fullscreen, .vis-fullscreen body{overflow:hidden}
  /* height/top are overwritten from window.visualViewport while open, so the
     panel tracks the keyboard; 100dvh is only the pre-script fallback. */
  .vis-fullscreen .vis-phone{position:fixed;left:0;right:0;top:0;height:100dvh;z-index:90;width:100%;max-width:none;margin:0;padding:0;border-radius:0;box-shadow:none}
  .vis-fullscreen .vis-phone::before{display:none}
  .vis-fullscreen .vis-wa{border-radius:0;height:100%}
  /* Only the conversation may take a drag; everything else refuses it, so
     the browser never starts a page scroll it would have to be talked out of. */
  .vis-fullscreen .vis-phone{touch-action:none}
  .vis-fullscreen .vis-chat{touch-action:pan-y}
  .vis-fullscreen .vis-chat{height:auto;flex:1;min-height:0}
  .vis-fullscreen .vis-wa__bar{padding-top:max(14px,env(safe-area-inset-top))}
  .vis-fullscreen .vis-wa__input{padding-bottom:max(14px,env(safe-area-inset-bottom))}
  .vis-fullscreen .vis-wa__back{cursor:pointer;padding:0 4px}
  .vis-fullscreen .vis-wa__back:focus-visible{outline:2px solid var(--vis-ochre);outline-offset:2px}
  .vis-fullscreen .vis-reset{display:none}
}

/* ---- start overlay ----
   Sits over the message stream only, so the header and the input row stay
   plainly visible — the point is that this is a working chat, not a picture of
   one. Ships hidden and is revealed by JS; see simulator.js. */
.vis-chat{position:relative}
/* .72, not less: the hint is 11px mono, and over the chat wallpaper a lighter
   scrim puts it at 4.04:1 — under the 4.5:1 floor. At .72 it reaches 6.3:1. */
.vis-start{position:absolute;inset:0;z-index:3;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:20px;text-align:center;background:rgba(22,21,15,.72);backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}
.vis-start[hidden]{display:none}
.vis-start__btn{border:none;cursor:pointer;background:var(--vis-ochre);color:var(--vis-ink);font-family:var(--vis-sans);font-weight:600;font-size:15px;line-height:1;height:46px;padding:0 24px}
.vis-start__btn:hover{background:var(--vis-ochre-deep)}
.vis-start__btn:focus-visible{outline:2px solid var(--vis-paper);outline-offset:2px}
.vis-start__hint{font-family:var(--vis-mono);font-size:11px;line-height:1.5;letter-spacing:.04em;color:#E8E2D5;max-width:22ch}

/* The hero CTA is a direct child of .vis-hero__inner, so it no longer inherits
   centring from .vis-hero__copy. Base rule = the stacked layout, where the rest
   of the hero is centred and ≤860px sets align-items:stretch; the two-column
   block below flips it back to flush left. */
.vis-btn-row--hero{justify-content:center;margin-top:34px}

/* ---- how it works ---- */
.vis-facts{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.vis-fact{background:var(--vis-white);border:1px solid var(--vis-hairline);border-radius:var(--vis-r-lg);padding:22px 22px 24px}
.vis-fact h3{font-size:16px;font-weight:600;letter-spacing:-0.012em;margin:0 0 7px;color:var(--vis-ink)}
.vis-fact p{margin:0;font-size:14.5px;line-height:1.55;color:var(--vis-body)}
.vis-fact--limit h3{padding-left:20px;position:relative}
.vis-fact--limit h3::before{content:"";position:absolute;left:0;top:9px;width:11px;height:2px;background:var(--vis-ochre);border-radius:1px}

.vis-flowsteps{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:1px;background:var(--vis-hairline);border:1px solid var(--vis-hairline);border-radius:var(--vis-r-lg);overflow:hidden}
.vis-flowstep{background:var(--vis-white);padding:20px 22px;display:grid;grid-template-columns:auto 1fr;gap:18px;align-items:start}
.vis-flowstep__n{font-family:var(--vis-mono);font-size:12.5px;font-weight:600;color:var(--vis-ochre-text);background:#fdf6e3;border:1px solid var(--vis-ochre-border,#f0cd7a);border-radius:var(--vis-r-sm);width:26px;height:26px;display:flex;align-items:center;justify-content:center}
.vis-flowstep h3{font-size:16px;font-weight:600;margin:0 0 5px;color:var(--vis-ink)}
.vis-flowstep p{margin:0;font-size:14.5px;line-height:1.55;color:var(--vis-body)}

.vis-statuses{display:flex;flex-direction:column;gap:10px;max-width:76ch}
.vis-status{display:grid;grid-template-columns:auto 1fr;gap:16px;align-items:start;background:var(--vis-white);border:1px solid var(--vis-hairline);border-radius:var(--vis-r-lg);padding:16px 20px}
.vis-status p{margin:0;font-size:14.5px;line-height:1.55;color:var(--vis-body)}
.vis-status__tag{font-size:12px;font-weight:600;padding:3px 9px;border-radius:var(--vis-r-sm);white-space:nowrap;border:1px solid}
.vis-status__tag--live{color:#067a52;background:#ecfdf5;border-color:#a7e8cd}
.vis-status__tag--soon{color:var(--vis-ochre-text);background:#fdf6e3;border-color:#f0cd7a}

/* ---- pricing page ----
   The intro is a page opening, not a section head, so it takes a page-sized
   title and a full prose measure. 42ch under a wide empty page reads as a
   stranded column. */
.vis-pricing__intro{display:flex;flex-direction:column;align-items:flex-start;gap:14px;max-width:62ch}
.vis-pricing__intro h1{font-size:clamp(34px,4.4vw,46px);line-height:1.06;letter-spacing:-0.03em;font-weight:600}
.vis-pricing__intro .vis-section__lede{max-width:none;font-size:17px;color:var(--vis-body)}
.vis-pricing__covers .vis-section__lede{max-width:58ch;font-size:16px}

/* ---- pricing tiers ----
   Same hairline grid as .vis-steps, so pricing reads as part of the site
   rather than a bolted-on template. The featured tier is marked by ground,
   not by a badge or a scale transform. */
.vis-tiers{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:36px}
.vis-tier{background:var(--vis-white);border:1px solid var(--vis-hairline);border-radius:var(--vis-r-lg);padding:26px 24px 24px;display:flex;flex-direction:column;gap:13px;transition:border-color var(--vis-dur) var(--vis-ease),box-shadow var(--vis-dur) var(--vis-ease)}
.vis-tier:hover{border-color:var(--vis-border-strong,#d4d4d1);box-shadow:var(--vis-shadow)}
.vis-tier--pick{border-color:var(--vis-ochre);box-shadow:var(--vis-shadow)}
.vis-tier__name{font-size:13px;font-weight:600;color:var(--vis-ochre-text)}
.vis-tier__price{font-size:38px;line-height:1;font-weight:600;letter-spacing:-0.03em;color:var(--vis-ink);margin:0;font-variant-numeric:tabular-nums}
.vis-tier__unit{font-size:14px;font-weight:400;letter-spacing:0;color:var(--vis-muted);margin-left:7px}
.vis-tier__who{font-size:14.5px;line-height:1.5;color:var(--vis-muted);margin:0}
.vis-tier__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px;font-size:15px;line-height:1.45}
.vis-tier__list li{padding-left:18px;position:relative}
.vis-tier__list li::before{content:"";position:absolute;left:0;top:8px;width:7px;height:1px;background:var(--vis-ochre-deep)}
.vis-tier .vis-btn{margin-top:auto}
.vis-tiers__fine{font-size:14px;line-height:1.6;color:var(--vis-muted);margin-top:22px;max-width:70ch}

/* ---- consent banner ----
   Same interaction as kkgconsulting.fi (modal until a choice is made, choice
   remembered 180 days), dressed in this site's materials: paper card, ink
   hairline, the ochre only on the affirmative action. z-index sits above the
   fullscreen demo phone (90). */
.vis-consent{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:20px;background:rgba(22,21,15,.55);backdrop-filter:blur(2px)}
.vis-consent[hidden]{display:none}
.vis-consent__card{max-width:430px;width:100%;background:var(--vis-white);border:1px solid var(--vis-ink);box-shadow:0 18px 50px rgba(22,21,15,.28);padding:26px clamp(22px,4vw,30px)}
.vis-consent__card h2{font-size:20px;font-weight:600;letter-spacing:-0.02em;margin:0 0 10px}
.vis-consent__card p{font-size:14.5px;line-height:1.6;color:var(--vis-body);margin:0 0 20px}
.vis-consent__card a{color:var(--vis-ink);text-decoration:underline;text-underline-offset:2px}
.vis-consent__actions{display:flex;gap:10px}
.vis-consent__actions .vis-btn{flex:1;justify-content:center;height:46px;font-size:15px}

/* ---- hero, two columns ----
   Wide viewports: copy, jobs and the fine print run down the left; the live
   demo sits to the right, spanning them. Below 1000px the phone (388px) plus
   readable copy no longer fit side by side, so it falls back to the stacked,
   centred layout above. Placed last: these override the .vis-stage and
   .vis-jobs base rules declared earlier in the file. */
@media (min-width:1000px){
  .vis-hero__inner{
    /* Tighter than the stacked layout's 52px: with the demo beside the copy
       rather than under it, the hero's job is to get both on screen. */
    --vis-hero-pt:24px;
    display:grid;
    grid-template-columns:minmax(0,1fr) auto;
    /* The demo is taller than the left column. Without a flexible last row,
       grid spreads its surplus height evenly across all three rows and tears
       a gap under the sub-headline; 1fr sends the slack to the bottom. */
    grid-template-rows:auto auto auto 1fr;
    column-gap:var(--vis-hero-gap);
    align-items:start;
    text-align:left;
  }
  .vis-hero__copy{grid-column:1;grid-row:1;align-items:flex-start;max-width:none;margin-bottom:0}
  /* One column, not two: as a list the four jobs scan faster, and the taller
     left rail sits closer in height to the demo beside it. */
  .vis-jobs{grid-column:1;grid-row:2;grid-template-columns:1fr;gap:18px;max-width:400px;margin-top:34px}
  /* Row 4 is deliberately left empty: it is the flexible track, so the height
     the demo has over the copy collects below the CTA rather than being shared
     out between the rows above it. */
  .vis-btn-row--hero{grid-column:1;grid-row:3;justify-content:flex-start;margin-top:34px}

  /* The demo gets its own dark stage: the panel starts halfway across the
     column gap and bleeds off the right edge (.vis-hero clips it). Insets are
     negative hero padding, so it meets the section's top and bottom rules. */
  /* No top padding: the badge is the panel's first line, sitting level with the
     headline across the gutter, and the phone hangs directly beneath it. The
     demo is what the page is for, so it starts as high as the copy does rather
     than being pushed down the page by its own label. */
  /* margin-block-start: WordPress's block layout puts 24px on every direct
     child of the hero group, which pushed the panel's contents below the
     headline. Zeroed so the badge lines up with it. */
  .vis-stage{grid-column:2;grid-row:1/span 4;align-self:start;position:relative;margin-block-start:0;padding:0 40px 44px;gap:6px}
  .vis-stage::before{content:'';position:absolute;top:calc(-1 * var(--vis-hero-pt));bottom:calc(-1 * var(--vis-hero-pb));left:calc(-1 * var(--vis-hero-gap) / 2);right:-100vw;background:var(--vis-sand);border-left:1px solid var(--vis-hairline);z-index:0}
  /* The panel bleeds to the viewport edge, so on a wide monitor its visual
     centre sits well right of the column. Nudge the contents back onto it —
     the shift grows with the viewport and caps, so it is nothing on a laptop.
     Applied to the children, never .vis-stage itself, which would drag ::before
     (the panel) along with them. */
  .vis-stage>*{position:relative;z-index:1;transform:translateX(clamp(0px,calc((100vw - var(--vis-max))/4),240px))}
  .vis-stage .vis-demo__note{color:var(--vis-ink-muted)}
}

