/* fipolo.com — shared styles
   Direction "Instrument": light, typographic, serif display, drawn graphics only.
   No photography anywhere on the site by decision; every illustration is inline SVG we
   author ourselves. The closest competitor shipped AI-generated hero art with garbled
   fake text visible at normal zoom — for a company selling measurement, imagery that
   does not survive being read is the worst possible first impression.

   Self-hosted font, no framework, no external requests of any kind. The site is a work
   sample for people who will judge how it is built. */

@font-face {
  font-family: "Instrument Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/instrument-serif-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;
}
@font-face {
  font-family: "Instrument Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/instrument-serif-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;
}
@font-face {
  font-family: "Instrument Serif";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/instrument-serif-italic-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;
}
@font-face {
  font-family: "Instrument Serif";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/instrument-serif-italic-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;
}

/* Both themes in one place. light-dark() resolves against the element's used color-scheme,
   so flipping color-scheme on <html> flips every variable at once — no second copy of the
   palette and no media query to keep in sync with the manual switch. Each variable is
   declared twice on purpose: the plain value first, so a browser without light-dark()
   still gets a working light theme instead of an unstyled page.

   The accent is a deep instrument green. Across eleven audited Prague competitors the
   accents were purple, royal blue, magenta, teal-orange, red, navy-orange, orange, lime,
   green-on-black and crimson — a dark forest green on warm paper is unclaimed, and it
   reads as measured rather than loud. */

:root {
  color-scheme: light dark;

  --bg: #fbfaf7;              --bg: light-dark(#fbfaf7, #0f1211);
  --bg-2: #f4f2ec;            --bg-2: light-dark(#f4f2ec, #161a19);
  --fg: #14171a;              --fg: light-dark(#14171a, #e9ebe8);
  --muted: #5a6160;           --muted: light-dark(#5a6160, #969d9a);
  --rule: #e0ddd4;            --rule: light-dark(#e0ddd4, #262c2a);
  --card: #ffffff;            --card: light-dark(#ffffff, #141918);
  --accent: #1f5138;          --accent: light-dark(#1f5138, #6fbf95);
  --accent-bg: #e8f0ea;       --accent-bg: light-dark(#e8f0ea, #15241d);
  --accent-fg: #ffffff;       --accent-fg: light-dark(#ffffff, #0f1211);

  /* CookieYes ships one light theme. The light values match what it already renders, so
     the override is a visual no-op by day and does the work by night. These use CookieYes's
     own class names — if they rename anything the banner just goes back to white at night. */
  --cky-bg: #ffffff;          --cky-bg: light-dark(#ffffff, #171d1b);
  --cky-rule: #e6e6e6;        --cky-rule: light-dark(#e6e6e6, #2a302e);
  --cky-text: #212121;        --cky-text: light-dark(#212121, #cfd4d1);
  --cky-title: #212121;       --cky-title: light-dark(#212121, #e9ebe8);
  --cky-accent: #1f5138;      --cky-accent: light-dark(#1f5138, #6fbf95);
  --cky-always: #008000;      --cky-always: light-dark(#008000, #7bc98a);
  --cky-switch: #d5d5d5;      --cky-switch: light-dark(#d5d5d5, #363c3a);
  --cky-accept-fg: #ffffff;   --cky-accept-fg: light-dark(#ffffff, #0f1211);

  --serif: "Instrument Serif", "Iowan Old Style", Palatino, Georgia, serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --maxw: 60rem;
  --bar: 3.5rem;
}

html[data-theme="light"] { color-scheme: light; }
html[data-theme="dark"] { color-scheme: dark; }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.65;
  text-wrap: pretty;
}

a { color: var(--accent); text-underline-offset: .18em; }
a:focus-visible, button:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 3px; }

.skip { position: absolute; left: -9999px; background: var(--card); color: var(--fg); padding: .6rem 1rem; z-index: 100; }
.skip:focus { left: .75rem; top: .75rem; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 1.5rem; }

/* ---- serif display ---- */

h1, h2, h3, .serif {
  font-family: var(--serif);
  font-weight: 400;
  letter-spacing: -.01em;
  line-height: 1.12;
  text-wrap: balance;
}
h1 { font-size: clamp(2.6rem, 7vw, 4.2rem); margin: 0 0 1rem; }
h2 { font-size: clamp(1.9rem, 4vw, 2.6rem); margin: 0 0 .5rem; }
h3 { font-size: 1.25rem; margin: 0 0 .4rem; line-height: 1.2; }
.lede { color: var(--muted); margin: 0 0 2rem; max-width: 44rem; font-size: 1.08rem; }
.muted { color: var(--muted); }
.small { font-size: .9rem; }

/* Section eyebrow — small caps sans against the serif heading, so each section announces
   itself without another type size. */
.eyebrow {
  font-family: var(--sans);
  font-size: .72rem; text-transform: uppercase; letter-spacing: .14em;
  color: var(--accent); font-weight: 650; margin: 0 0 .7rem;
}

/* ---- sticky bar ---- */

.bar {
  position: sticky; top: 0; z-index: 50; height: var(--bar);
  display: flex; align-items: center;
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--rule);
}
.bar .wrap { display: flex; align-items: center; gap: 1rem; width: 100%; }
.bar-name {
  font-family: var(--serif); font-size: 1.28rem; color: var(--fg);
  text-decoration: none; margin-right: auto; display: flex; align-items: center; gap: .55rem;
}
.bar-name .dot { width: .44rem; height: .44rem; border-radius: 50%; background: var(--accent); }
.bar nav { display: flex; gap: 1.1rem; overflow-x: auto; scrollbar-width: none; }
.bar nav::-webkit-scrollbar { display: none; }
.bar nav a { color: var(--muted); text-decoration: none; font-size: .9rem; white-space: nowrap; }
.bar nav a:hover, .bar nav a[aria-current="page"] { color: var(--fg); }
.bar-tools { display: flex; align-items: center; gap: .5rem; }
.lang { font-size: .8rem; color: var(--muted); text-decoration: none; border: 1px solid var(--rule); border-radius: 999px; padding: .15rem .55rem; }
.lang:hover { color: var(--fg); }
.theme-btn {
  border: 1px solid var(--rule); background: transparent; color: var(--muted);
  border-radius: 999px; width: 2rem; height: 2rem; cursor: pointer; line-height: 1;
  display: grid; place-items: center; padding: 0;
}
.theme-btn:hover { color: var(--fg); }
.theme-btn .moon { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-btn .sun { display: none; }
  :root:not([data-theme="light"]) .theme-btn .moon { display: block; }
}
:root[data-theme="dark"] .theme-btn .sun { display: none; }
:root[data-theme="dark"] .theme-btn .moon { display: block; }
/* The nav is never hidden. On a one-page site a hidden bar costs nothing; on a four-page site
   it is the only way to reach three quarters of the content, and a hamburger for four links is
   a worse trade than letting the row scroll. Below 46rem the brand shortens and the row scrolls. */
@media (max-width: 46rem) {
  .bar { height: auto; padding: .5rem 0; }
  .bar .wrap { flex-wrap: wrap; gap: .5rem .7rem; }
  .bar-name { font-size: 1.1rem; margin-right: auto; }
  .bar nav { order: 3; width: 100%; gap: .95rem; padding-bottom: .1rem; -webkit-overflow-scrolling: touch; }
  .bar nav a { font-size: .86rem; }
  main section { padding-top: 3rem; }
  .hero { padding-top: 2.5rem; }
}

/* ---- sections ---- */

main section { padding: 4.5rem 0 1rem; scroll-margin-top: calc(var(--bar) + 1.5rem); }
.band { background: var(--bg-2); border-block: 1px solid var(--rule); margin-top: 3rem; }
.band section { padding-block: 4rem 3rem; }

/* ---- hero ---- */

.hero { padding-top: 5rem; }
.hero .claim { font-size: 1.22rem; margin: 0 0 1.1rem; max-width: 40rem; }
.hero .sub { color: var(--muted); margin: 0 0 1.8rem; max-width: 42rem; }
.hero h1 em { font-style: italic; color: var(--accent); }

/* Industries, not numbers: the company has no published metrics yet, and inventing them
   would break the "never invent proof" rule. Sectors are true today and can be swapped
   for numbers the moment there are numbers worth showing. */
.sectors { display: flex; flex-wrap: wrap; gap: .5rem 1.6rem; align-items: baseline;
  padding: 1.2rem 0; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); margin: 0; }
.sectors dt { font-size: .72rem; text-transform: uppercase; letter-spacing: .14em; color: var(--muted); width: 100%; margin-bottom: .2rem; }
.sectors dd { margin: 0; font-family: var(--serif); font-size: 1.32rem; }
.sectors dd + dd::before { content: "·"; color: var(--rule); margin-right: 1.6rem; }

/* ---- drawn graphics ---- */

figure.diagram { margin: 2.4rem 0 0; }
figure.diagram svg { width: 100%; height: auto; display: block; }
figure.diagram figcaption { color: var(--muted); font-size: .86rem; margin-top: .7rem; }
.dg-stroke { stroke: var(--rule); }
.dg-ink { stroke: var(--fg); }
.dg-accent { stroke: var(--accent); }
.dg-fill-card { fill: var(--card); }
.dg-fill-accent { fill: var(--accent); }
.dg-label { fill: var(--fg); font-family: var(--sans); font-size: 11px; }
.dg-sub { fill: var(--muted); font-family: var(--sans); font-size: 9.5px; }
.dg-flow { stroke-dasharray: 4 5; animation: dgflow 3s linear infinite; }
@keyframes dgflow { to { stroke-dashoffset: -18; } }
@media (prefers-reduced-motion: reduce) { .dg-flow { animation: none; } }

.svc-icon { width: 2.5rem; height: 2.5rem; display: block; margin-bottom: .9rem; }
.svc-icon [stroke] { stroke: var(--accent); }

/* ---- cards ---- */

.cards { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); }
.cards-2 { grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); }

/* Four across, explicitly. auto-fit gave three plus an orphan on the last row at this column
   width, which reads as a mistake rather than as a set. The summary cards on the home page
   carry an icon, a heading and two lines, so they survive the narrower column. */
.cards-4 { grid-template-columns: 1fr; }
@media (min-width: 34rem) { .cards-4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 62rem) {
  .cards-4 { grid-template-columns: repeat(4, 1fr); gap: .85rem; }
  .cards-4 .card { padding: 1.1rem 1.1rem 1.2rem; }
  .cards-4 .card h3 { font-size: 1.12rem; }
  .cards-4 .card p { font-size: .92rem; }
  .cards-4 .svc-icon { width: 2.1rem; height: 2.1rem; margin-bottom: .7rem; }
}
.card { background: var(--card); border: 1px solid var(--rule); border-radius: 4px; padding: 1.4rem 1.5rem 1.5rem; }
.card .meta { font-size: .78rem; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); margin: 0 0 .5rem; }
.card p { margin: 0 0 .7rem; font-size: .97rem; }
.card .deliver { font-size: .92rem; color: var(--muted); margin-bottom: 0; }
.card .deliver strong { color: var(--fg); font-weight: 600; }
.card ul.links { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .3rem .8rem; font-size: .88rem; }
.card ul.links a { text-decoration: none; }
.card ul.links a:hover { text-decoration: underline; }

.group-label { font-size: .72rem; text-transform: uppercase; letter-spacing: .14em; color: var(--muted); margin: 2.4rem 0 1rem; font-weight: 650; }

/* ---- capability tiers ---- */

.tier { margin: 1.8rem 0 0; }
.pills { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .4rem; }
.pills li { border: 1px solid var(--rule); background: var(--card); border-radius: 3px; padding: .3rem .7rem; font-size: .88rem; }
.tier-daily .pills li { border-color: color-mix(in srgb, var(--accent) 40%, var(--rule)); background: var(--accent-bg); }

/* ---- process ---- */

.steps { list-style: none; counter-reset: s; margin: 1.4rem 0 0; padding: 0; display: grid; gap: 1rem; }
.steps li { counter-increment: s; display: grid; grid-template-columns: 2.2rem 1fr; gap: 1rem; align-items: start; }
/* grid-row: span 2 matters — without it the <span> wraps onto the next grid line and lands
   back in the 2.2rem number column, which squeezes one sentence into a 700px-tall sliver. */
.steps li::before {
  content: counter(s, decimal-leading-zero);
  grid-row: span 2;
  font-family: var(--serif); font-size: 1.05rem; color: var(--accent);
  border-top: 1px solid var(--accent); padding-top: .2rem;
}
.steps strong { display: block; font-weight: 600; }
.steps span { color: var(--muted); font-size: .96rem; }

/* ---- company / contact ---- */

.idcard { background: var(--card); border: 1px solid var(--rule); border-radius: 4px; padding: 1.3rem 1.5rem; margin-top: 1.4rem; }
/* Each <div> is one row, and inside it the label/value pair is its own two-column grid.
   Making the <dl> itself two columns puts two unrelated pairs side by side instead. */
.idcard dl { display: grid; gap: .4rem; margin: .8rem 0 0; font-size: .92rem; }
.idcard dl > div { display: grid; grid-template-columns: 7.5rem 1fr; gap: 0 1rem; align-items: baseline; }
.idcard dt { color: var(--muted); }
.idcard dd { margin: 0; }
.idcard > strong { font-size: 1.15rem; }
@media (max-width: 30rem) { .idcard dl > div { grid-template-columns: 1fr; } .idcard dt { font-size: .8rem; } }

.cta { background: var(--accent-bg); border: 1px solid color-mix(in srgb, var(--accent) 28%, var(--rule)); border-radius: 4px; padding: 1.6rem 1.7rem; margin-top: 1.4rem; }
.cta p { margin: 0 0 1.1rem; }
.actions { display: flex; flex-wrap: wrap; gap: .6rem; }
.btn { display: inline-block; text-decoration: none; font-size: .97rem; font-weight: 550; border-radius: 3px; padding: .62rem 1.15rem; background: var(--accent); color: var(--accent-fg); border: 1px solid var(--accent); }
.btn:hover { filter: brightness(1.12); }
.btn-quiet { background: transparent; color: var(--accent); }
.hero-cta { display: flex; flex-wrap: wrap; gap: .6rem; margin: 1.8rem 0 2.2rem; }

footer.foot { border-top: 1px solid var(--rule); margin-top: 4.5rem; padding: 2.2rem 0 3rem; color: var(--muted); font-size: .88rem; }

/* ---- CookieYes dark-mode overrides ---- */
.cky-consent-container .cky-consent-bar, .cky-modal, .cky-preference-center { background: var(--cky-bg) !important; border-color: var(--cky-rule) !important; }
.cky-title, .cky-preference-title, .cky-accordion-header .cky-accordion-btn { color: var(--cky-title) !important; }
.cky-notice-des *, .cky-preference-body-wrapper *, .cky-accordion-header-des * { color: var(--cky-text) !important; }
.cky-btn-accept, .cky-btn-reject, .cky-btn-preferences, .cky-btn-customize { border-color: var(--cky-accent) !important; }
.cky-btn-accept { background: var(--cky-accent) !important; color: var(--cky-accept-fg) !important; }
.cky-always-active { color: var(--cky-always) !important; }
.cky-switch input { background: var(--cky-switch) !important; }

/* ============================================================================
   Craft layer — the things that stop a generated page from looking generated.
   Each one is small; the effect is cumulative.
   ========================================================================= */

/* Paper grain. A single inline SVG turbulence, no image request, barely visible — but it
   removes the dead flatness of a pure #fbfaf7 fill. */
.grain {
  position: fixed; inset: 0; z-index: 1; pointer-events: none;
  opacity: .035; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}
:root[data-theme="dark"] .grain { opacity: .05; mix-blend-mode: screen; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .grain { opacity: .05; mix-blend-mode: screen; } }

/* Hand-drawn underline under the one italic word in each h1. Two strokes with slightly
   different curvature, because a pen never repeats itself exactly. Draws itself on load. */
.em-wrap { position: relative; display: inline-block; white-space: nowrap; }
.em-wrap .ul {
  position: absolute; left: -1%; bottom: -.08em; width: 102%; height: .34em;
  overflow: visible; pointer-events: none;
}
.em-wrap .ul path {
  fill: none; stroke: var(--accent); stroke-width: 2.4; stroke-linecap: round;
  opacity: .9; vector-effect: non-scaling-stroke;
  stroke-dasharray: 1; stroke-dashoffset: 1;
  animation: draw 1.1s cubic-bezier(.65,0,.35,1) .35s forwards;
}
.em-wrap .ul .ul-2 { stroke-width: 1.4; opacity: .45; animation-delay: .5s; animation-duration: 1.3s; }
@keyframes draw { to { stroke-dashoffset: 0; } }
@media (prefers-reduced-motion: reduce) { .em-wrap .ul path { animation: none; stroke-dashoffset: 0; } }

/* Marginalia. On a wide screen it sits out in the margin like a pencil note; on a narrow one
   it folds back into the column. */
.note {
  font-family: var(--serif); font-style: italic; font-size: 1rem; line-height: 1.5;
  color: var(--muted); max-width: 22rem; margin: 1.6rem 0 0;
  padding-left: 1rem; border-left: 1px solid var(--rule);
}
/* Only float the note into the margin when the viewport is genuinely wide enough to hold it
   beside a 60rem column — otherwise it overflows the window instead of sitting in a margin. */
@media (min-width: 96rem) {
  .note { position: absolute; right: -17.5rem; width: 15.5rem; margin-top: 0; font-size: .95rem; }
  .diagram { position: relative; }
}

/* Pull quote. The one place the serif runs large and unaccompanied. */
.pull { margin: 1rem 0 0; padding: 0; border: 0; }
.pull p {
  font-family: var(--serif); font-size: clamp(1.7rem, 3.6vw, 2.5rem); line-height: 1.22;
  margin: 0 0 .7rem; text-wrap: balance; max-width: 34rem;
}
.pull p::before { content: "\201C"; color: var(--accent); margin-left: -.5em; }
.pull p::after { content: "\201D"; color: var(--accent); }
.pull cite { font-style: normal; font-size: .84rem; text-transform: uppercase; letter-spacing: .12em; color: var(--muted); }

/* "More" link with a rule that extends on hover, instead of a button. */
.more { margin: 2rem 0 0; }
.more a {
  text-decoration: none; font-size: .95rem; display: inline-flex; align-items: center; gap: .55rem;
}
.more a::after {
  content: ""; width: 2.2rem; height: 1px; background: var(--accent);
  transition: width .28s cubic-bezier(.65,0,.35,1);
}
.more a:hover::after { width: 3.6rem; }

/* Scroll reveal. Everything marked .r starts slightly low and faded, and settles as it comes
   into view. Staggered per section so a section arrives as a sequence, not a slab.
   Two safeguards, because a reveal that fails leaves an invisible page: no-JS keeps everything
   visible, and reduced-motion skips the movement entirely. */
.r { opacity: 1; }
.js .r { opacity: 0; transform: translateY(14px); }
.js .r.in { opacity: 1; transform: none; transition: opacity .45s ease, transform .45s cubic-bezier(.22,1,.36,1); }
@media (prefers-reduced-motion: reduce) {
  .js .r, .js .r.in { opacity: 1; transform: none; transition: none; }
}

/* Cards lift very slightly — enough to feel alive, not enough to bounce. */
.card { transition: transform .25s cubic-bezier(.22,1,.36,1), border-color .25s ease; }
.card:hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--accent) 35%, var(--rule)); }

/* The diagram's flow lines only animate once the figure is on screen, so nothing is moving
   in a part of the page nobody is looking at. */
.diagram:not(.in) .dg-flow { animation-play-state: paused; }

footer.foot .wrap { padding-inline: 1.5rem; }
footer.foot p { margin: 0 0 .3rem; }
main section { position: relative; }
