/* site.css — public marketing pages. Deliberately separate from the app's style.css:
   the app optimises for density, the site optimises for reading.

   Theme: modern SaaS "trust" palette — deep navy ink, primary blue (#2563EB),
   cyan highlights on dark surfaces, cool off-white bands, generous radii and
   glassmorphism (translucent surfaces + backdrop blur) on the hero, CTA and
   feature cards. Clarity first: high contrast text, visible focus rings,
   reduced-motion support.

   No external assets (CDNs, hotlinked fonts, remote images): Montserrat is
   self-hosted below so the strict `font-src 'self'` CSP holds and pages render
   offline. Montserrat by Julieta Ulanovsky et al., SIL Open Font License 1.1 —
   files unmodified from Google Fonts, redistribution expressly permitted. */

/* latin-ext — downloaded only when a page uses a character in this range */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('montserrat-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('montserrat-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --ink: #0F1D33;          /* deep navy-slate */
  --ink-soft: #33445F;
  --muted: #5D6C84;
  --line: #DCE4F0;
  --line-soft: #EAEFF7;
  --bg: #ffffff;
  --tint: #F5F8FD;         /* cool blue-tinted band ground */
  --deep: #0A1E4A;         /* trust navy — hero / dark bands */
  --deep-2: #081737;       /* deeper navy — footer */
  --accent: #2563EB;       /* primary trust blue */
  --accent-deep: #1D4ED8;
  --accent-ink: #ffffff;
  --accent-soft: #E8F0FE;
  --bright: #38BDF8;       /* cyan — accents on navy */
  --warn: #B45309;
  --warn-bg: #FEF7EC;
  --bad: #B91C1C;
  --good: #15803D;
  --sans: 'Montserrat', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  --r: 16px;               /* soft, modern */
  --r-btn: 10px;
  --shadow: 0 1px 2px rgba(13, 38, 76, .05), 0 14px 40px rgba(13, 38, 76, .08);
  --glass: rgba(255, 255, 255, .72);
  --glass-border: rgba(255, 255, 255, .55);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}
::selection { background: #CFE1FD; }
img, svg { max-width: 100%; }
/* A long unbreakable token (a code, a URL, a Finnish compound) must wrap rather
   than push the page wider than the phone. No effect at desktop widths. */
h1, h2, h3, h4, p, li, td, th, dt, dd, summary { overflow-wrap: break-word; }
a { color: var(--accent); }
.wrap { width: 100%; max-width: 1120px; margin: 0 auto; padding: 0 24px; }
.wrap.narrow { max-width: 820px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Accessibility foundations: a consistent focus ring everywhere, anchor targets
   that clear the sticky header, and a skip link for keyboard users. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.hero :focus-visible, .cta :focus-visible, section.band.dark :focus-visible, .foot :focus-visible { outline-color: var(--bright); }
[id] { scroll-margin-top: 84px; }
.skip { position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--accent); color: #fff; font-weight: 700; text-decoration: none;
  padding: 10px 18px; border-radius: 0 0 10px 0; }
.skip:focus { left: 0; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ------------------------------------------------------------------ header */
.nav {
  position: sticky; top: 0; z-index: 50;
  background: rgba(255, 255, 255, .78);
  backdrop-filter: saturate(160%) blur(14px);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid var(--line-soft);
}
.nav-in { display: flex; align-items: center; gap: 22px; height: 64px; }
.brand { display: inline-flex; align-items: center; gap: 9px; font-weight: 800; font-size: 1.06rem; letter-spacing: -.01em; color: var(--ink); text-decoration: none; }
.brand .loop { width: 24px; height: 24px; flex: none; color: var(--accent); }
.brand em { font-style: normal; color: var(--accent); }
.nav-links { display: flex; gap: 20px; margin-left: 8px; }
.nav-links a { color: var(--ink-soft); text-decoration: none; font-size: .93rem; font-weight: 600; }
.nav-links a:hover, .nav-links a[aria-current="page"] { color: var(--accent); }
.nav-end { margin-left: auto; display: flex; align-items: center; gap: 12px; }
.nav select {
  border: 1px solid var(--line); border-radius: 9px; padding: 5px 7px;
  font: inherit; font-size: .85rem; color: var(--ink-soft); background: #fff;
}
.nav-toggle { display: none; background: none; border: 1px solid var(--line); border-radius: 9px; padding: 6px 9px; cursor: pointer; }
.nav-toggle span { display: block; width: 17px; height: 2px; background: var(--ink); margin: 3px 0; border-radius: 2px; }
.only-mobile { display: none; }

/* ------------------------------------------------- reference dropdown ("Resources")
   The four reference pages sit behind one top-level item. The panel is absolutely
   positioned, so opening it never moves Features or Pricing. It lives inside the
   sticky header's stacking context (.nav, z-index 50) and is raised within it, so it
   paints over the hero and every other page section. Same surface language as the
   cards: white ground, --line border, --r radius, --shadow. */
.nav-drop { position: relative; display: flex; align-items: center; }
.nav-drop-btn {
  display: inline-flex; align-items: center; gap: 5px;
  margin: 0; padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: .93rem; font-weight: 600; line-height: inherit;
  color: var(--ink-soft);
}
/* .current is set by site.js when one of the four pages inside is the page we are on,
   so the top level keeps the position marker the flat nav had. */
.nav-drop-btn:hover, .nav-drop-btn[aria-expanded="true"], .nav-drop-btn.current { color: var(--accent); }
.nav-drop-chev { width: 13px; height: 13px; flex: none; transition: transform .16s ease; }
.nav-drop-btn[aria-expanded="true"] .nav-drop-chev { transform: rotate(180deg); }
.nav-drop-menu {
  position: absolute; top: calc(100% + 20px); left: -10px; z-index: 60;
  display: flex; flex-direction: column; gap: 2px;
  min-width: 226px; padding: 8px;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--shadow);
}
.nav-drop-menu[hidden] { display: none; }
/* Invisible bridge across the gap under the button: the pointer can travel from the
   button into the panel without leaving the group. */
.nav-drop-menu::before { content: ''; position: absolute; left: 0; right: 0; top: -20px; height: 20px; }
.nav-links .nav-drop-menu a {
  display: flex; align-items: center; min-height: 40px;
  padding: 8px 12px; border-radius: 9px; white-space: nowrap;
}
.nav-links .nav-drop-menu a:hover,
.nav-links .nav-drop-menu a:focus-visible,
.nav-links .nav-drop-menu a[aria-current="page"] { background: var(--tint); }
/* The group label is for the collapsed phone menu only — on desktop the button says it. */
.nav-drop-title { display: none; }
/* Without JavaScript there is no toggle, so hover and focus open the panel instead.
   site.js adds .js and then owns the state, which is why this cannot fight it (and
   why Escape can never be undone by the button still being focused). */
.nav-drop:not(.js):hover .nav-drop-menu[hidden],
.nav-drop:not(.js):focus-within .nav-drop-menu[hidden] { display: flex; }

/* ------------------------------------------------------------------ buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 12px 22px; border-radius: var(--r-btn); border: 1px solid transparent;
  font: inherit; font-size: .95rem; font-weight: 700; text-decoration: none;
  cursor: pointer; white-space: nowrap; transition: transform .12s ease, filter .12s ease, border-color .12s ease, color .12s ease, box-shadow .12s ease;
}
.btn.primary { background: var(--accent); color: var(--accent-ink); box-shadow: 0 8px 22px rgba(37, 99, 235, .28); }
.btn.primary:hover { filter: brightness(1.07); transform: translateY(-1px); }
.btn.ghost { background: #fff; color: var(--ink); border-color: var(--line); }
.btn.ghost:hover { border-color: var(--accent); color: var(--accent); }
.btn.on-dark { background: #fff; color: var(--deep); box-shadow: 0 8px 26px rgba(2, 8, 30, .35); }
.btn.on-dark:hover { transform: translateY(-1px); box-shadow: 0 10px 30px rgba(2, 8, 30, .45); }
.btn.ghost-dark { background: rgba(255, 255, 255, .06); color: rgba(255, 255, 255, .92); border-color: rgba(255, 255, 255, .28); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.btn.ghost-dark:hover { border-color: var(--bright); color: #fff; }
.btn.small { padding: 8px 15px; font-size: .88rem; }
.btn-row { display: flex; flex-wrap: wrap; gap: 12px; }

/* --------------------------------------------------------------------- hero */
.hero {
  background:
    radial-gradient(640px 420px at 84% -10%, rgba(56, 189, 248, .28), transparent 65%),
    radial-gradient(560px 420px at -6% 108%, rgba(124, 108, 246, .22), transparent 62%),
    linear-gradient(158deg, var(--deep) 0%, #10306E 58%, #123A7C 100%);
  color: #fff; overflow: hidden; position: relative;
}
.hero-in { padding: 76px 0 80px; position: relative; z-index: 1; display: grid; grid-template-columns: 1.08fr .92fr; gap: 54px; align-items: center; }
.eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: .78rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--bright); margin-bottom: 18px;
}
.eyebrow .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--bright); }
.hero h1 { font-size: clamp(2.15rem, 4.7vw, 3.25rem); line-height: 1.08; letter-spacing: -.028em; margin: 0 0 20px; font-weight: 800; text-wrap: balance; }
.hero h1 em { font-style: normal; color: var(--bright); }
.hero p.sub { font-size: 1.1rem; color: rgba(255, 255, 255, .78); margin: 0 0 28px; max-width: 34em; }
.hero .fine { margin-top: 18px; font-size: .84rem; color: rgba(255, 255, 255, .56); }

/* ------------------------------------------------------------- trust badges */
.trust { border-bottom: 1px solid var(--line-soft); background: #fff; }
.trust-in { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px 26px; padding: 18px 0; }
.trust-badge { display: inline-flex; align-items: center; gap: 8px; font-size: .86rem; font-weight: 600; color: var(--ink-soft); white-space: nowrap; }
.trust-badge svg { width: 17px; height: 17px; color: var(--accent); flex: none; }

/* ------------------------------------------------------------------ sections */
section.band { padding: 76px 0; }
section.band.tinted {
  background:
    radial-gradient(620px 320px at 12% 12%, rgba(37, 99, 235, .05), transparent 70%),
    radial-gradient(560px 320px at 88% 88%, rgba(56, 189, 248, .07), transparent 70%),
    var(--tint);
}
section.band.dark {
  background:
    radial-gradient(620px 400px at 88% 0%, rgba(56, 189, 248, .16), transparent 65%),
    linear-gradient(158deg, var(--deep) 0%, #10306E 100%);
  color: rgba(255, 255, 255, .84);
}
section.band.dark h2, section.band.dark h3 { color: #fff; }
section.band.dark p { color: rgba(255, 255, 255, .72); }
.head { max-width: 42em; margin-bottom: 40px; }
.head.center { margin-left: auto; margin-right: auto; text-align: center; }
.head .kicker { font-size: .78rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--accent); }
section.band.dark .head .kicker { color: var(--bright); }
h2 { font-size: clamp(1.6rem, 3vw, 2.1rem); line-height: 1.18; letter-spacing: -.022em; margin: 8px 0 14px; font-weight: 800; text-wrap: balance; }
h3 { font-size: 1.08rem; margin: 0 0 8px; font-weight: 700; letter-spacing: -.01em; }
.head p, .lede { color: var(--ink-soft); font-size: 1.03rem; margin: 0; }

/* ------------------------------------------------------------------- layout */
.cols { display: grid; gap: 22px; }
.cols.c2 { grid-template-columns: repeat(2, 1fr); }
.cols.c3 { grid-template-columns: repeat(3, 1fr); }
.cols.c4 { grid-template-columns: repeat(4, 1fr); }
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; }

/* Glass cards: translucent over the tinted bands' soft color glows. */
.card {
  background: var(--glass);
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  border: 1px solid var(--glass-border);
  border-radius: var(--r); padding: 24px; box-shadow: var(--shadow);
}
.card.plain { box-shadow: none; }
.card p { color: var(--ink-soft); font-size: .95rem; margin: 0; }
.card .ico { width: 34px; height: 34px; color: var(--accent); margin-bottom: 14px; display: block; }
section.band.dark .card { background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .16); box-shadow: none; }
section.band.dark .card .ico { color: var(--bright); }

.stat { text-align: left; }
.stat .n { font-size: 2.4rem; font-weight: 800; letter-spacing: -.03em; color: var(--accent); line-height: 1.05; font-variant-numeric: tabular-nums; }
section.band.dark .stat .n { color: var(--bright); }
.stat .l { font-size: .9rem; color: var(--ink-soft); }
section.band.dark .stat .l { color: rgba(255, 255, 255, .72); }

/* numbered steps */
.steps { counter-reset: s; display: grid; gap: 14px; }
.step { display: grid; grid-template-columns: 40px 1fr; gap: 16px; align-items: start; background: var(--glass); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border: 1px solid var(--glass-border); border-radius: var(--r); padding: 18px 20px; box-shadow: var(--shadow); }
.step::before {
  counter-increment: s; content: counter(s);
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--accent); color: #fff; font-weight: 700; font-size: .95rem;
  display: flex; align-items: center; justify-content: center;
}
.step p { margin: 4px 0 0; color: var(--ink-soft); font-size: .94rem; }

/* checklist */
ul.ticks { list-style: none; margin: 16px 0 0; padding: 0; }
ul.ticks li { position: relative; padding: 6px 0 6px 30px; font-size: .96rem; color: var(--ink-soft); }
ul.ticks li::before {
  content: ''; position: absolute; left: 2px; top: 12px;
  width: 14px; height: 8px; border-left: 2.5px solid var(--accent); border-bottom: 2.5px solid var(--accent);
  transform: rotate(-45deg);
}
/* Something a plan does not include. A muted dash, never a tick — the tick means
   "you get this" everywhere else on the site and must not be borrowed. */
ul.ticks li.no { color: var(--muted); }
ul.ticks li.no::before {
  top: 17px; left: 3px; width: 13px; height: 0;
  border-left: none; border-bottom: 2.5px solid #B9C4D6; transform: none;
}
section.band.dark ul.ticks li { color: rgba(255, 255, 255, .8); }
section.band.dark ul.ticks li::before { border-color: var(--bright); }

/* ------------------------------------------------------------------- tables */
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r); background: #fff; }
table.ref { border-collapse: collapse; width: 100%; font-size: .92rem; }
table.ref th, table.ref td { text-align: left; padding: 11px 14px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
table.ref thead th { background: var(--tint); font-size: .76rem; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); font-weight: 700; position: sticky; top: 0; }
table.ref tbody tr:last-child td { border-bottom: none; }
table.ref tbody tr:hover { background: var(--tint); }
/* A labelled band inside a comparison table — a section heading, not a data row. */
table.ref tr.grp th { background: var(--tint); font-size: .74rem; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); font-weight: 800; }
table.ref .mono { font-variant-numeric: tabular-nums; font-weight: 700; }
table.ref .mark svg { width: 40px; height: auto; display: block; }

.pill { display: inline-block; padding: 2px 10px; border-radius: 99px; font-size: .72rem; font-weight: 700; letter-spacing: .02em; white-space: nowrap; }
.pill.good { background: #E3F5EB; color: var(--good); }
.pill.warn { background: #FBEDDB; color: var(--warn); }
.pill.bad { background: #FBE0E0; color: var(--bad); }
.pill.neutral { background: #E7ECF4; color: var(--ink-soft); }

/* filter row on reference pages */
.filters { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 18px; }
.filters input, .filters select {
  padding: 9px 12px; border: 1px solid var(--line); border-radius: var(--r-btn);
  font: inherit; font-size: .92rem; background: #fff; color: var(--ink);
}
.filters input { min-width: 240px; flex: 1 1 240px; max-width: 380px; }
.filters input:focus-visible, .filters select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.count { color: var(--muted); font-size: .88rem; align-self: center; }

/* --------------------------------------------------------------------- FAQ */
.faq details { border-bottom: 1px solid var(--line); }
.faq summary { cursor: pointer; padding: 18px 0; font-weight: 700; font-size: 1.02rem; list-style: none; display: flex; justify-content: space-between; gap: 16px; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: '+'; color: var(--accent); font-weight: 700; font-size: 1.3rem; line-height: 1; flex: none; }
.faq details[open] summary::after { content: '−'; }
.faq .a { padding: 0 0 20px; color: var(--ink-soft); font-size: .97rem; max-width: 60em; }
.faq .a p { margin: 0 0 10px; }
.faq .a p:last-child { margin: 0; }

/* --------------------------------------------------------------------- CTA */
.cta {
  background:
    radial-gradient(560px 360px at 88% -20%, rgba(56, 189, 248, .24), transparent 65%),
    radial-gradient(480px 320px at 0% 120%, rgba(124, 108, 246, .2), transparent 62%),
    linear-gradient(150deg, var(--deep) 0%, #10306E 100%);
  color: #fff; border-radius: 22px; padding: 48px; text-align: center; position: relative; overflow: hidden;
  box-shadow: 0 24px 60px rgba(2, 8, 30, .25);
}
.cta h2 { color: #fff; margin-top: 0; }
.cta p { color: rgba(255, 255, 255, .76); max-width: 34em; margin: 0 auto 26px; }
.cta .btn-row { justify-content: center; }

/* ------------------------------------------------------------------- plans */
/* Stated once, above the cards: the scope that does not vary by tier. Keeping it
   out of the cards is what stops the cards implying a market or brand limit. */
.alltiers {
  background: #fff; border: 1px solid var(--line); border-radius: var(--r);
  padding: 22px 26px; margin-bottom: 26px; box-shadow: var(--shadow);
}
.alltiers h3 { font-size: 1.05rem; margin: 0; }
.alltiers ul.ticks { margin-top: 10px; display: grid; grid-template-columns: 1fr 1fr; gap: 0 28px; }
.alltiers p { margin: 14px 0 0; color: var(--muted); font-size: .9rem; }

.plans { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; align-items: start; }
.plan { background: #fff; border: 1px solid var(--line); border-radius: var(--r); padding: 28px 26px; position: relative; box-shadow: var(--shadow); }
.plan.featured { border: 2px solid var(--accent); box-shadow: 0 1px 2px rgba(13, 38, 76, .05), 0 18px 50px rgba(37, 99, 235, .18); }
.plan .flag { position: absolute; top: -13px; left: 50%; transform: translateX(-50%); background: var(--accent); color: #fff; font-size: .72rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; padding: 4px 14px; border-radius: 99px; }
.plan h3 { font-size: 1.15rem; margin-bottom: 2px; }
.plan .who { color: var(--muted); font-size: .88rem; min-height: 2.6em; }
.plan .price { font-size: 2.4rem; font-weight: 800; letter-spacing: -.03em; margin: 14px 0 2px; font-variant-numeric: tabular-nums; }
.plan .price small { font-size: .92rem; font-weight: 500; color: var(--muted); letter-spacing: 0; }
.plan .btn { width: 100%; margin: 18px 0 4px; }

/* ------------------------------------------------------------------ footer */
.foot { background: var(--deep-2); color: #93A1B8; padding: 56px 0 30px; font-size: .9rem; }
.foot a { color: #C6D2E4; text-decoration: none; }
.foot a:hover { color: #fff; }
.foot-cols { display: grid; grid-template-columns: 1.6fr repeat(4, 1fr); gap: 30px; }

/* Cookie consent. Fixed to the bottom, above everything, and narrow enough on a phone
   that it never covers the whole page. */
.consent { position: fixed; left: 16px; right: 16px; bottom: 16px; z-index: 60;
  display: flex; flex-wrap: wrap; gap: 14px; align-items: center; justify-content: space-between;
  max-width: 720px; margin: 0 auto; padding: 14px 18px;
  background: rgba(10, 30, 74, .92); color: rgba(255, 255, 255, .92);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 14px; box-shadow: 0 12px 40px rgba(0, 0, 0, .35); font-size: .9rem; }
.consent p { margin: 0; flex: 1 1 260px; line-height: 1.5; }
.consent p a { color: var(--bright); }
/* Accept and Decline share one class and one minimum width on purpose: rejecting must be
   exactly as easy and as prominent as accepting (GDPR consent), so neither button may
   render smaller or visually recessive relative to the other. */
.consent-btns { display: flex; gap: 8px; flex: 0 0 auto; }
.consent-btns .btn { min-width: 104px; }
/* The current decision shown when the banner is reopened from "Cookie settings". */
.consent .consent-status { display: block; font-weight: 700; margin: 0 0 4px; }
/* The runtime-injected "Cookie settings" link in the footer legal line: underlined so it
   reads as an action amid the disclaimer prose. */
.foot .legal a { color: #C6D2E4; text-decoration: underline; }
.foot .legal a:hover { color: #fff; }

/* Legal documents. Narrower measure than the marketing pages — these are read, not
   scanned — and numbered lists that carry their own numbers, because clauses get cited. */
.legal { max-width: 46em; }
.legal h2 { margin: 34px 0 10px; font-size: 1.25rem; }
.legal h3 { margin: 22px 0 6px; font-size: 1rem; }
.legal p { line-height: 1.65; margin: 0 0 12px; }
.legal .ticks { margin: 8px 0 16px; }
.legal-ol { margin: 8px 0 16px 1.2em; padding: 0; line-height: 1.65; }
.legal-ol li { margin: 0 0 8px; }
.legal-note { font-size: .88rem; color: var(--muted); }
.legal-blank { color: var(--muted); }
.legal-callout { border: 1px solid var(--line); border-left: 4px solid var(--bad);
  background: #FFF6F6; border-radius: 10px; padding: 14px 16px; margin: 14px 0; line-height: 1.6; }
.legal-id { border: 1px solid var(--line); border-radius: 12px; padding: 16px 18px; background: #fff; margin: 0 0 26px; }
.legal-id dl { display: grid; grid-template-columns: minmax(9em, max-content) 1fr; gap: 6px 18px; margin: 0; }
.legal-id dt { font-weight: 700; font-size: .85rem; color: var(--muted); }
.legal-id dd { margin: 0; }
.legal-id-warn { background: var(--warn-bg); border: 1px solid #F0D9AE; border-radius: 10px;
  padding: 10px 12px; margin: 0 0 14px; font-size: .9rem; line-height: 1.55; }
@media (max-width: 560px) { .legal-id dl { grid-template-columns: 1fr; gap: 2px 0; }
  .legal-id dd { margin: 0 0 8px; } }
.foot h4 { color: #fff; font-size: .76rem; letter-spacing: .1em; text-transform: uppercase; margin: 0 0 12px; }
.foot ul { list-style: none; margin: 0; padding: 0; }
.foot li { margin: 7px 0; }
.foot .legal { border-top: 1px solid rgba(255, 255, 255, .12); margin-top: 36px; padding-top: 20px; font-size: .82rem; color: #6E7E97; }

/* ---------------------------------------------------------------- responsive */
@media (max-width: 960px) {
  .hero-in { grid-template-columns: 1fr; gap: 36px; padding: 56px 0 60px; }
  .split { grid-template-columns: 1fr; gap: 32px; }
  .cols.c3, .cols.c4 { grid-template-columns: repeat(2, 1fr); }
  .plans { grid-template-columns: 1fr; }
  .foot-cols { grid-template-columns: 1fr 1fr; gap: 26px; }
}
@media (max-width: 720px) {
  body { font-size: 16px; }
  .nav-links { display: none; position: absolute; top: 64px; left: 0; right: 0; background: #fff; border-bottom: 1px solid var(--line); flex-direction: column; gap: 0; padding: 8px 24px 16px; margin: 0; }
  .nav-links.open { display: flex; }
  .nav-links a { padding: 11px 0; border-bottom: 1px solid var(--line-soft); }
  .nav-toggle { display: block; order: 3; }
  .nav-in { gap: 12px; }
  /* Picker + two buttons + toggle do not fit at phone width: the calls to action
     move into the collapsed menu rather than widening the page. */
  .nav-end #nav-signin, .nav-end #nav-cta { display: none; }
  .only-mobile { display: block; color: var(--accent); font-weight: 600; }
  .cols.c2, .cols.c3, .cols.c4 { grid-template-columns: 1fr; }
  section.band { padding: 54px 0; }
  .cta { padding: 34px 22px; }
  .foot-cols { grid-template-columns: 1fr; }
  .trust-in { gap: 8px 18px; }
  .alltiers ul.ticks { grid-template-columns: 1fr; }

  /* Header tap targets. The hamburger and the language picker are the only two
     controls left in the bar, so both have to be thumb-sized, and the collapsed
     menu has to scroll when it is taller than the viewport (landscape phones). */
  .nav-toggle { display: flex; flex-direction: column; align-items: center; justify-content: center; width: 44px; height: 44px; padding: 0; }
  .nav select { padding: 9px 8px; font-size: .9rem; min-height: 40px; }
  .nav-links { max-height: calc(100vh - 64px); overflow-y: auto; -webkit-overflow-scrolling: touch; }
  .nav-links a { display: flex; align-items: center; min-height: 44px; padding: 10px 0; }

  /* No dropdown inside the collapsed menu. A panel hanging off a panel is a trap on a
     phone, so the group is simply always open: the button drops out of the document
     entirely (nothing extra to tap, nothing extra in the tab order) and the four
     reference pages become ordinary full-width rows, indented under a muted label.
     The menu stays inside .nav-links, so it scrolls with it on a short landscape screen. */
  .nav-drop { display: block; }
  .nav-drop-btn { display: none; }
  .nav-drop-menu, .nav-drop-menu[hidden] {
    display: flex; position: static; z-index: auto; min-width: 0; gap: 0; padding: 0;
    background: none; border: 0; border-radius: 0; box-shadow: none;
  }
  .nav-drop-menu::before { display: none; }
  .nav-drop-title {
    display: block; padding: 14px 0 2px; color: var(--muted);
    font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  }
  .nav-links .nav-drop-menu a {
    min-height: 44px; padding: 10px 0 10px 14px; border-radius: 0; white-space: normal;
  }

  /* Wide reference tables scroll inside their wrapper instead of squeezing every
     column down to one word per line — the body itself never scrolls sideways.
     The gradients are the affordance: the white covers travel with the content
     (background-attachment: local) and hide the edge shadows only when there is
     nothing further to scroll in that direction. */
  table.ref.wide { min-width: 720px; }
  table.ref.xwide { min-width: 880px; }
  .table-wrap {
    -webkit-overflow-scrolling: touch;
    background:
      linear-gradient(to right, #fff 30%, rgba(255, 255, 255, 0)) 0 0 / 42px 100% no-repeat local,
      linear-gradient(to left, #fff 30%, rgba(255, 255, 255, 0)) 100% 0 / 42px 100% no-repeat local,
      radial-gradient(farthest-side at 0 50%, rgba(13, 38, 76, .17), rgba(13, 38, 76, 0)) 0 0 / 15px 100% no-repeat scroll,
      radial-gradient(farthest-side at 100% 50%, rgba(13, 38, 76, .17), rgba(13, 38, 76, 0)) 100% 0 / 15px 100% no-repeat scroll,
      #fff;
  }

  /* Filter rows: one control per line, thumb-sized, never wider than the page. */
  .filters { gap: 8px; }
  .filters input, .filters select { min-height: 40px; }
  .filters input { flex: 1 1 100%; min-width: 0; max-width: none; }
  .filters select { flex: 1 1 100%; max-width: 100%; }
}

/* Two-column definition tables (the DPA annex) read better stacked than squeezed. */
@media (max-width: 560px) {
  table.ref.rows, table.ref.rows tbody, table.ref.rows tr, table.ref.rows th, table.ref.rows td { display: block; }
  table.ref.rows tr { border-bottom: 1px solid var(--line-soft); padding: 6px 0; }
  table.ref.rows tr:last-child { border-bottom: none; }
  table.ref.rows th { border-bottom: none; padding: 8px 14px 0; font-size: .74rem; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
  table.ref.rows td { border-bottom: none; padding-top: 2px; }
}

/* Small phones (~360px and down). The header row — brand, picker, hamburger —
   is what runs out of width first, so the gutters and the heavy card padding
   give some of it back. Nothing here applies above 480px. */
@media (max-width: 480px) {
  .wrap { padding: 0 16px; }
  .nav-in { gap: 10px; }
  /* the menu is positioned against the header, not the wrap — align it by hand */
  .nav-links { padding-left: 16px; padding-right: 16px; }
  .brand { font-size: .98rem; gap: 7px; }
  .card, .step { padding: 20px 18px; }
  .plan { padding: 24px 20px; }
  .alltiers { padding: 20px 18px; }
  .cta { padding: 30px 18px; }
  .consent { left: 10px; right: 10px; bottom: 10px; padding: 12px 14px; }
}
@media print { .nav, .cta, .foot, .skip { display: none; } }

/* ============================================ by-Toolcat branding & mockups */
.brand .by { font-size: .58em; font-weight: 600; color: var(--muted); letter-spacing: .01em; margin-left: .35em; white-space: nowrap; }
header.nav .brand .by { color: var(--muted); }

/* app screenshot mockups (self-contained CSS "browser" frames) */
.shots { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; align-items: start; }
@media (max-width: 900px) { .shots { grid-template-columns: 1fr; max-width: 460px; margin: 0 auto; } }
.mock { border: 1px solid var(--line); border-radius: 14px; overflow: hidden; box-shadow: var(--shadow); background: #fff; }
.shot { width: 100%; height: auto; display: block; }
.mock-bar { display: flex; align-items: center; gap: 6px; padding: 9px 12px; background: var(--tint); border-bottom: 1px solid var(--line); }
.mock-bar i { width: 9px; height: 9px; border-radius: 50%; background: #CBD5E4; display: inline-block; }
.mock-bar span { margin-left: 8px; font-family: var(--mono); font-size: 11px; color: var(--muted); }
.mock-screen { padding: 14px; font-size: 12px; min-height: 172px; }
.mock-cap { text-align: center; font-size: .92rem; color: var(--ink-soft); margin-top: 12px; font-weight: 600; }
.mock-cap small { display: block; color: var(--muted); font-weight: 400; font-size: .82rem; margin-top: 2px; }
.rr { display: flex; align-items: center; justify-content: space-between; padding: 7px 9px; border: 1px solid var(--line-soft); border-radius: 8px; margin-bottom: 6px; }
.rr b { font-weight: 600; font-size: 11.5px; color: var(--ink-soft); }
.pill { font-size: 10px; font-weight: 800; letter-spacing: .03em; padding: 2px 8px; border-radius: 20px; color: #fff; }
.pill.g { background: var(--good); } .pill.a { background: #D97706; } .pill.r { background: var(--bad); } .pill.n { background: #8CA0B8; }
.docm h4 { margin: 0 0 7px; font-size: 12px; letter-spacing: .02em; color: var(--ink); font-weight: 800; }
.docm .tabs { display: flex; gap: 5px; margin-bottom: 9px; }
.docm .tabs b { font-size: 10px; padding: 2px 8px; border-radius: 6px; background: var(--tint); color: var(--muted); font-weight: 700; }
.docm .tabs b.on { background: var(--accent); color: #fff; }
.docm .ln { height: 7px; border-radius: 4px; background: var(--line-soft); margin: 6px 0; }
.docm .ln.s { width: 58%; } .docm .ln.m { width: 84%; }
.docm .sig { margin-top: 12px; border-top: 1px dashed var(--line); padding-top: 8px; font-size: 10.5px; color: var(--muted); }
.wzm .step { font-size: 10px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); }
.wzm .q { font-weight: 700; font-size: 12.5px; margin: 5px 0 9px; color: var(--ink); }
.wzm .opt { padding: 7px 9px; border: 1px solid var(--line); border-radius: 8px; margin-bottom: 6px; font-size: 11.5px; color: var(--ink-soft); }
.wzm .opt.sel { border-color: var(--accent); background: var(--accent-soft); color: var(--ink); font-weight: 600; }
.wzm .prog { height: 5px; background: var(--line-soft); border-radius: 3px; margin-top: 12px; overflow: hidden; }
.wzm .prog i { display: block; height: 100%; width: 68%; background: var(--accent); }

/* free "Partner" tier callout */
.partner {
  border: 1px solid rgba(37, 99, 235, .35); border-radius: var(--r); padding: 26px 28px;
  background: linear-gradient(135deg, rgba(232, 240, 254, .9), rgba(255, 255, 255, .82));
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  display: grid; grid-template-columns: 1.5fr 1fr; gap: 24px; align-items: center; margin-bottom: 30px;
  box-shadow: 0 1px 2px rgba(13, 38, 76, .05), 0 18px 50px rgba(37, 99, 235, .14);
}
@media (max-width: 760px) { .partner { grid-template-columns: 1fr; text-align: center; } }
.partner .tag { display: inline-block; font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); background: #fff; border: 1px solid rgba(37, 99, 235, .4); border-radius: 99px; padding: 3px 12px; margin-bottom: 12px; }
.partner h3 { margin: 0 0 8px; font-size: 1.5rem; }
.partner p { margin: 0; color: var(--ink-soft); font-size: .96rem; }
.partner .free { font-size: 2.4rem; font-weight: 800; color: var(--accent); line-height: 1; }
.partner .free small { display: block; font-size: .9rem; font-weight: 600; color: var(--muted); margin-top: 4px; }
.partner .side { text-align: center; }

/* ============================================ material-mark generator (tool) */
/* Public tool on material-marks.html: controls beside a live preview. Form controls
   are styled here because the marketing surface loads only site.css — the app's dense
   style.css is not present on these pages. No external assets. */
.markgen { display: grid; grid-template-columns: 1.05fr .95fr; gap: 30px; align-items: start; }
.markgen-controls { display: grid; gap: 16px; }
.mg-field { display: grid; gap: 6px; font-size: .78rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.mg-field small { font-weight: 500; text-transform: none; letter-spacing: 0; color: var(--muted); font-size: .82rem; }
.mg-field select,
.mg-field input[type="text"] {
  font: inherit; font-size: .95rem; font-weight: 400; text-transform: none; letter-spacing: 0;
  color: var(--ink); background: #fff; border: 1px solid var(--line); border-radius: var(--r-btn);
  padding: 10px 12px; width: 100%;
}
.mg-field input[type="color"] {
  width: 100%; height: 44px; padding: 4px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-btn); background: #fff;
}
.mg-field select:focus-visible,
.mg-field input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.mg-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.mg-checks { display: flex; flex-wrap: wrap; gap: 10px 22px; }
.mg-check { display: inline-flex; align-items: center; gap: 8px; font-size: .95rem; font-weight: 600; color: var(--ink-soft); text-transform: none; }
.mg-check input { width: 16px; height: 16px; accent-color: var(--accent); }
.mg-hint { font-size: .9rem; color: var(--ink-soft); line-height: 1.5; }
.mg-hint:empty { display: none; }
.mg-hint b, .mg-hint code { color: var(--ink); font-weight: 700; }
.mg-note { font-size: .84rem; color: var(--muted); line-height: 1.5; margin: 4px 0 0; }
.markgen-preview {
  position: sticky; top: 84px; text-align: center;
  background: var(--tint); border: 1px solid var(--line); border-radius: var(--r); padding: 24px;
}
.mg-preview-head { font-size: .76rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-bottom: 16px; }
.mg-preview {
  display: flex; align-items: center; justify-content: center; min-height: 260px;
  background: #fff; border: 1px solid var(--line-soft); border-radius: var(--r-btn); padding: 20px;
}
.mg-preview svg { display: block; width: auto; height: 240px; max-width: 100%; }
.mg-preview-note { font-size: .82rem; color: var(--muted); margin: 14px 0 0; }
@media (max-width: 760px) {
  .markgen { grid-template-columns: 1fr; }
  .markgen-preview { position: static; }
  .mg-grid { grid-template-columns: 1fr; }
}
/* Small-phone padding for the two components declared below the responsive block
   above — they would otherwise win on source order and keep their desktop inset. */
@media (max-width: 480px) {
  .partner { padding: 22px 18px; }
  .markgen-preview { padding: 18px 14px; }
  .mg-preview { padding: 14px; min-height: 220px; }
  .mg-preview svg { height: 200px; }
}

/* ================================================ workflow chart (workflow.html) */
/* A public map of the whole compliance road: a vertical trunk of steps the visitor
   walks, and side branches for the steps where the app produces the document instead.
   Design rules this block obeys:

   * The trunk is the site's primary blue; the side branches are the violet already
     present in the hero and CTA gradients (rgba(124,108,246,…)). Violet is used because
     the compliance traffic light — red required, amber declared, green on file, white
     done — is frozen semantics and none of those four colours may be borrowed for
     decoration. The one green on this page is the end node's tick, where green means
     exactly what it means everywhere else: pass.
   * Connector geometry is fixed user units with no viewBox on the SVG, so one user unit
     is one CSS pixel. The dash lengths below are therefore the true lengths of the
     lines, and the draw animation needs no runtime measurement.
   * Everything the visitor reads is in the DOM as soon as a role is picked; the
     animation only moves opacity and stroke-dashoffset. That is what makes the
     reduced-motion block at the end a complete answer rather than a degraded one. */
:root {
  --wf-side: #6D5CE7;         /* the violet already in the hero / CTA gradients */
  --wf-side-soft: #F3F1FE;
  --wf-side-line: #BFB4F4;
  --wf-trunk: #B9CBEA;
}

/* Left-aligned, not centred: the trunk is a spine and it has to start on the same
   vertical as the section heading above it, or the whole chart reads as nudged. */
.wf { max-width: 940px; margin: 0; }

/* ------------------------------------------------------------- role picker */
.wf-roles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.wf-role {
  display: grid; gap: 7px; justify-items: start; text-align: left; margin: 0;
  font: inherit; cursor: pointer;
  background: #fff; border: 1.5px solid var(--line); border-radius: var(--r);
  padding: 20px; box-shadow: var(--shadow);
  transition: border-color .15s ease, transform .15s ease, box-shadow .15s ease, background .15s ease;
}
.wf-role:hover { border-color: var(--accent); transform: translateY(-2px); }
.wf-role[aria-pressed="true"] {
  border-color: var(--accent); background: var(--accent-soft);
  box-shadow: 0 1px 2px rgba(13, 38, 76, .05), 0 16px 38px rgba(37, 99, 235, .18);
}
.wf-role-ico { width: 30px; height: 30px; color: var(--accent); }
.wf-role-name { font-weight: 800; font-size: 1.05rem; letter-spacing: -.012em; color: var(--ink); }
.wf-role-desc { font-size: .89rem; color: var(--ink-soft); line-height: 1.45; }

.wf-noscript { margin: 22px 0 0; color: var(--ink-soft); font-size: .95rem; }

/* ------------------------------------------------------------------ legend */
.wf-legend { display: flex; flex-wrap: wrap; gap: 8px 24px; margin: 22px 0 0; font-size: .83rem; font-weight: 600; color: var(--muted); }
.wf-leg { display: inline-flex; align-items: center; gap: 9px; }
.wf-leg i { width: 24px; height: 0; flex: none; border-top: 2.5px solid var(--accent); }
.wf-leg-side i { border-top-color: var(--wf-side); border-top-style: dashed; }

/* ------------------------------------------------------------ progress bar */
.wf-summary {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px;
  margin: 20px 0 2px; padding: 11px 16px;
  background: #fff; border: 1px solid var(--line); border-radius: 12px;
}
.wf-summary[hidden] { display: none; }
.wf-sum-role { font-weight: 800; color: var(--ink); font-size: .96rem; }
.wf-sum-count { font-size: .85rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.wf-skip {
  margin-left: auto; padding: 4px 2px; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: .84rem; font-weight: 700; color: var(--accent); text-decoration: underline;
}
.wf-skip[hidden] { display: none; }

/* --------------------------------------------------------- trunk connector */
/* 46 px of line, drawn from the step above toward the step below, then a dot lands on
   the far end. x = 38 is the centre of the numbered badge: 20 px card padding + 1 px
   border + half of a 34 px badge. Change one and change the other. */
.wf-flow { position: relative; }
.wf-link { line-height: 0; }
.wf-link-svg { display: block; overflow: visible; }
.wf-link-line {
  stroke: var(--wf-trunk); stroke-width: 2.5; stroke-linecap: round;
  stroke-dasharray: 46; stroke-dashoffset: 46;
  transition: stroke-dashoffset .3s ease;
}
.wf-link.drawn .wf-link-line { stroke-dashoffset: 0; }
.wf-link-dot { fill: var(--accent); opacity: 0; transition: opacity .2s ease .24s; }
.wf-link.drawn .wf-link-dot { opacity: 1; }

/* ----------------------------------------------------------------- the row */
.wf-row {
  display: grid; grid-template-columns: minmax(0, 1fr) 374px; align-items: start;
  opacity: 0; transform: translateY(10px);
  transition: opacity .34s ease, transform .34s ease;
}
.wf-row.on { opacity: 1; transform: none; }
.wf-cell { position: relative; min-width: 0; }

/* --------------------------------------------------------------- step card */
.wf-node {
  display: grid; grid-template-columns: 34px minmax(0, 1fr) 18px; gap: 14px; align-items: start;
  width: 100%; margin: 0; text-align: left; font: inherit; cursor: pointer;
  background: var(--glass);
  backdrop-filter: blur(12px) saturate(160%); -webkit-backdrop-filter: blur(12px) saturate(160%);
  border: 1px solid var(--glass-border); border-radius: var(--r);
  padding: 16px 18px 16px 20px; box-shadow: var(--shadow);
  transition: border-color .14s ease, box-shadow .14s ease;
}
.wf-node:hover { border-color: var(--accent); }
.wf-node[aria-expanded="true"] { border-color: var(--accent); box-shadow: 0 1px 2px rgba(13, 38, 76, .05), 0 16px 38px rgba(37, 99, 235, .18); }
.wf-badge {
  width: 34px; height: 34px; border-radius: 50%; flex: none;
  background: var(--accent); color: #fff; font-weight: 800; font-size: .92rem;
  display: inline-flex; align-items: center; justify-content: center;
  font-variant-numeric: tabular-nums;
}
.wf-node-main { display: grid; gap: 3px; min-width: 0; padding-top: 4px; }
.wf-node-title { font-weight: 700; font-size: 1.02rem; line-height: 1.3; letter-spacing: -.012em; color: var(--ink); }
.wf-node-chip { font-size: .82rem; color: var(--muted); line-height: 1.4; }
.wf-chev { width: 18px; height: 18px; margin-top: 12px; color: var(--muted); transition: transform .16s ease, color .16s ease; }
.wf-node[aria-expanded="true"] .wf-chev { transform: rotate(180deg); color: var(--accent); }

/* ------------------------------------------------------------- side branch */
/* Visually a different kind of thing: violet instead of blue, a dashed border instead
   of a solid one, no drop shadow. It is not a step the visitor has to walk. */
.wf-branch { display: grid; grid-template-columns: 54px minmax(0, 1fr); align-items: start; }
.wf-branch-svg { display: block; width: 54px; height: 70px; margin-top: 4px; overflow: visible; }
.wf-bl-h, .wf-bl-v { stroke: var(--wf-side); stroke-width: 2.5; stroke-linecap: round; transition: stroke-dashoffset .28s ease; }
.wf-bl-h { stroke-dasharray: 54; stroke-dashoffset: 54; }
.wf-bl-v { stroke-dasharray: 30; stroke-dashoffset: 30; display: none; }
.wf-branch.drawn .wf-bl-h, .wf-branch.drawn .wf-bl-v { stroke-dashoffset: 0; }
.wf-side {
  display: grid; gap: 6px; width: 100%; margin: 0; text-align: left; font: inherit; cursor: pointer;
  background: var(--wf-side-soft); border: 1.5px dashed var(--wf-side-line);
  border-radius: 14px; padding: 12px 15px;
  transition: border-color .14s ease, background .14s ease;
}
.wf-side:hover, .wf-side[aria-expanded="true"] { border-color: var(--wf-side); background: #EBE7FD; }
.wf-side-tag { display: inline-flex; align-items: center; gap: 6px; font-size: .68rem; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--wf-side); }
.wf-side-ico { width: 15px; height: 15px; flex: none; }
.wf-side-title { font-weight: 700; font-size: .94rem; line-height: 1.35; color: var(--ink); }

/* ---------------------------------------------------------------- end node */
.wf-end {
  display: grid; grid-template-columns: 40px minmax(0, 1fr); gap: 16px; align-items: start;
  background: radial-gradient(420px 260px at 92% -30%, rgba(56, 189, 248, .22), transparent 65%),
    linear-gradient(150deg, var(--deep) 0%, #10306E 100%);
  color: #fff; border-radius: var(--r); padding: 20px 22px;
  box-shadow: 0 18px 44px rgba(2, 8, 30, .22);
}
.wf-end-mark {
  width: 40px; height: 40px; border-radius: 50%;
  background: rgba(255, 255, 255, .12); border: 1px solid rgba(255, 255, 255, .22);
  display: inline-flex; align-items: center; justify-content: center;
}
/* Green, and green means what it always means here: pass. Not the app's --good, which
   is tuned for white grounds and goes muddy on navy — this is the same on-dark green
   the hero's live indicator uses. */
.wf-end-ico { width: 21px; height: 21px; color: #34D399; }
.wf-end-main { display: grid; gap: 5px; }
.wf-end-title { font-weight: 800; font-size: 1.1rem; letter-spacing: -.018em; }
.wf-end-body { font-size: .92rem; line-height: 1.5; color: rgba(255, 255, 255, .78); }

/* ------------------------------------------------------------- step panels */
/* A disclosure, not a hover tooltip: the trigger is a button with aria-expanded, so it
   works on a phone, from a keyboard and in a screen reader. One is open at a time. */
.wf-panel {
  position: absolute; z-index: 42; top: calc(100% + 9px); left: 0;
  width: min(352px, 100%);
  background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 15px 16px;
  box-shadow: 0 2px 6px rgba(13, 38, 76, .06), 0 22px 50px rgba(13, 38, 76, .18);
}
.wf-panel[hidden] { display: none; }
.wf-panel::before {
  content: ''; position: absolute; top: -7px; left: 26px; width: 12px; height: 12px;
  background: #fff; border-left: 1px solid var(--line); border-top: 1px solid var(--line);
  transform: rotate(45deg); border-radius: 3px 0 0 0;
}
.wf-panel p { margin: 0 0 9px; font-size: .89rem; line-height: 1.5; color: var(--ink-soft); }
.wf-panel p:last-child { margin-bottom: 0; }
.wf-panel-note { color: var(--ink); font-weight: 600; }
.wf-panel-needs { background: var(--tint); border-radius: 9px; padding: 9px 11px; font-size: .88rem; color: var(--ink); }
.wf-panel-ref { font-size: .77rem; color: var(--muted); border-top: 1px solid var(--line-soft); padding-top: 9px; }
/* The side panel hangs from the right edge, so a 360 px panel on a 320 px card grows
   inward over the connector rather than outward past the page. */
.wf-branch .wf-panel { left: auto; right: 0; width: 340px; max-width: 100%; }
.wf-branch .wf-panel::before { left: auto; right: 26px; }

/* The click that closes an open panel. Transparent: it exists to catch the click, not to
   dim the page. Triggers are lifted above it so a click straight onto another step opens
   that step instead of costing a second tap. */
.wf-backdrop { position: fixed; inset: 0; z-index: 40; background: transparent; }
.wf.wf-open .wf-node, .wf.wf-open .wf-side,
.wf.wf-open .wf-role, .wf.wf-open .wf-skip { position: relative; z-index: 41; }

/* ------------------------------------------------------------- the numbers */
.wf-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; max-width: 940px; margin: 0 auto 34px; }
.wf-stats[hidden] { display: none; }
.wf-stat { background: #fff; border: 1px solid var(--line); border-radius: var(--r); padding: 22px 24px; box-shadow: var(--shadow); }
.wf-stat .n { font-size: 2.6rem; font-weight: 800; line-height: 1.05; letter-spacing: -.03em; color: var(--accent); font-variant-numeric: tabular-nums; }
.wf-stat .l { margin-top: 4px; font-size: .9rem; line-height: 1.45; color: var(--ink-soft); }

.wf-caption {
  max-width: 62em; margin: 26px auto 0; padding: 14px 16px;
  background: #fff; border: 1px solid var(--line); border-left: 4px solid var(--wf-side);
  border-radius: 10px; font-size: .92rem; line-height: 1.55; color: var(--ink-soft);
}
.wf-caption[hidden] { display: none; }

/* --------------------------------------------------------------- responsive */
@media (max-width: 860px) {
  .wf-row { grid-template-columns: minmax(0, 1fr) 300px; }
}
/* At phone width the chart becomes one column. The trunk is unchanged — the line still
   grows downward at x = 38 — and the side branch turns from a horizontal spur into a
   short drop with the card indented under it. Panels come in-flow so they can never be
   wider than the viewport. */
@media (max-width: 720px) {
  .wf-roles { grid-template-columns: 1fr; gap: 12px; }
  .wf-row { grid-template-columns: 1fr; }
  .wf-branch { display: block; padding-left: 38px; }
  .wf-branch-svg { width: 100%; height: 30px; margin-top: 0; }
  .wf-bl-h { display: none; }
  .wf-bl-v { display: block; }
  .wf-panel,
  .wf-branch .wf-panel {
    position: relative; z-index: 42; top: auto; left: auto; right: auto;
    width: auto; max-width: none; margin-top: 10px;
    box-shadow: 0 1px 2px rgba(13, 38, 76, .05), 0 10px 26px rgba(13, 38, 76, .1);
  }
  .wf-panel::before, .wf-branch .wf-panel::before { display: none; }
  .wf-stats { grid-template-columns: 1fr; gap: 14px; }
  .wf-stat { padding: 18px 20px; }
  .wf-stat .n { font-size: 2.1rem; }
}
@media (max-width: 480px) {
  /* The left-hand geometry (20 px padding, 34 px badge) is what the trunk line is drawn
     against, so only the right-hand side gives way on a small phone. */
  .wf-node { padding-right: 14px; gap: 12px; }
  .wf-node-title { font-size: .97rem; }
  .wf-role { padding: 17px 18px; }
  .wf-end { padding: 18px 18px; gap: 13px; }
  .wf-panel { padding: 14px 15px; }
}

/* Motion here is narration, never information: the same chart, drawn all at once. */
@media (prefers-reduced-motion: reduce) {
  .wf-link-line, .wf-bl-h, .wf-bl-v { stroke-dashoffset: 0 !important; }
  .wf-link-dot { opacity: 1 !important; }
  .wf-row { opacity: 1 !important; transform: none !important; }
}

/* ------------------------------------------------------------ hero product shot */
/* The hero carries a real screenshot of the compliance dossier rather than a widget:
   it says what the product is faster than any copy can. The screenshot is captured at
   1384x784 from the running application, so the column is rebalanced and the image
   allowed a small bleed past it — at 1384 CSS px that lands the shot near the 692 px
   the feature-page shots are shown at, which is the size the app's own type stays
   readable at. .hero already clips (overflow: hidden), so the bleed can never widen
   the page. */
.hero-in { grid-template-columns: .96fr 1.04fr; gap: 46px; }
.hero-shot-fig { margin: 0; min-width: 0; }
.hero-shot {
  display: block; width: 100%; max-width: none; height: auto;
  border-radius: 14px; border: 1px solid rgba(255, 255, 255, .22);
  box-shadow: 0 30px 70px rgba(2, 8, 30, .45);
}
/* The bleed only where the viewport actually has room for it. Below this the image
   would run past the right edge and .hero would clip the readiness panel off the
   screenshot — losing the very thing the picture is there to show. */
@media (min-width: 1332px) { .hero-shot { width: calc(100% + 96px); } }
.hero-shot-cap {
  margin-top: 12px; font-size: .82rem; line-height: 1.45;
  color: rgba(255, 255, 255, .62); max-width: 34em;
}

@media (max-width: 960px) {
  /* Stacked: no bleed, and the shot keeps the full column width. */
  .hero-in { grid-template-columns: 1fr; }
  .hero-shot { width: 100%; }
}

/* ------------------------------------------------- footer business identity */
/* The yritystiedot block at the foot of every public page — company, business ID, address
   and the contact channels — filled by site.js from the operator's legal settings. It is
   `hidden` in the markup and only revealed once there is something to publish, so a fresh
   instance shows an ordinary footer rather than a row of empty labels. When it is shown it
   takes over the divider from the disclaimer line beneath it instead of drawing a second
   rule two lines below the first; when it is not, that line keeps its own. */
.foot-id {
  border-top: 1px solid rgba(255, 255, 255, .12);
  margin-top: 36px; padding-top: 20px;
  font-size: .85rem; line-height: 1.65;
}
.foot-id h4 { margin: 0 0 6px; }
.foot-id p { margin: 0; }
.foot-id b { color: #C6D2E4; }
.foot-id:not([hidden]) + .legal { border-top: 0; margin-top: 14px; padding-top: 0; }
@media (max-width: 720px) { .foot-id { margin-top: 26px; } }
