/*
Theme Name: Portfolio
Theme URI: https://example.com/portfolio
Author: Mati
Description: Lekki block theme pod portfolio. Pełne wsparcie Full Site Editing, zero buildera, optymalizacja pod Core Web Vitals.
Version: 0.1.7
Requires at least: 6.7
Tested up to: 6.9
Requires PHP: 8.2
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: portfolio
Tags: block-theme, full-site-editing, portfolio, blog
*/

/* ----------------------------------------------------------------------
   Base layer. tokens.css and fonts.css load first; this file styles
   element defaults that theme.json can't express declaratively (focus
   states beyond outline, hover transitions, custom utility classes
   used by patterns).
   ---------------------------------------------------------------------- */

/* Card style variation — applied via class is-style-card on group/columns.
   Patterns reference this rather than re-declaring border/radius/shadow
   inline; the token values can change in tokens.css and every card
   updates. */
.is-style-card {
  position: relative;
  overflow: hidden;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--lg);
  padding: var(--wp--preset--spacing--40);
  transition: var(--wp--custom--transition--base);
}
.is-style-card:hover {
  background: var(--surface-3);
  border-color: var(--brand);
  transform: translateY(-2px);
  box-shadow: var(--shadow-card-lifted);
}

/* Brand-soft corner decoration. Geometric, single-color, low alpha so
   it reads as texture rather than ornament. Hover bumps to full
   opacity to telegraph interactivity without a heavy lift. */
.card-deco {
  position: absolute;
  top: -1rem;
  right: -1rem;
  pointer-events: none;
  opacity: 0.6;
  transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.is-style-card:hover .card-deco {
  opacity: 1;
}

/* Eyebrow — small uppercase label above hero headlines */
.is-style-eyebrow {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.8125rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--brand);
  font-weight: 500;
}

/* Pill — rounded chip for stack tags, status labels */
.is-style-pill {
  display: inline-flex;
  align-items: center;
  padding: 0.25rem 0.625rem;
  border-radius: var(--wp--custom--radius--pill);
  background: var(--surface-3);
  color: var(--ink-muted);
  font-size: 0.8125rem;
  font-family: var(--wp--preset--font-family--plex-mono);
  border: 1px solid var(--border);
}

/* Mono — utility for inline code, stat numbers, eyebrow labels */
.is-style-mono {
  font-family: var(--wp--preset--font-family--plex-mono);
}

/* Inline SVG icons embedded in patterns inherit currentColor */
.icon {
  width: 1.25rem;
  height: 1.25rem;
  vertical-align: -0.25em;
  flex-shrink: 0;
}

/* Buttons — extend theme.json's button styles with hover transition */
.wp-block-button .wp-block-button__link {
  transition: var(--wp--custom--transition--base);
}
.wp-block-button .wp-block-button__link:hover {
  transform: translateY(-1px);
}

/* Outlined button variant — override the theme.json filled style */
.wp-block-button.is-style-outline .wp-block-button__link {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--border-strong);
}
.wp-block-button.is-style-outline .wp-block-button__link:hover {
  background: var(--surface-2);
  border-color: var(--ink);
}

/* Skip-to-content link — accessibility staple */
.skip-link {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
.skip-link:focus {
  left: 1rem;
  top: 1rem;
  width: auto;
  height: auto;
  padding: 0.5rem 1rem;
  background: var(--surface);
  color: var(--ink);
  border: 2px solid var(--brand);
  border-radius: var(--wp--custom--radius--md);
  z-index: 9999;
}

/* Comfortable reading measure for prose post-content. The :not(.alignfull)
   guard is critical: alignfull post-content is used by service-page-style
   templates where the content fills the viewport so section bleeds + wide
   card grids work; clamping it to 68ch would clip every alignwide child
   inside back to ~680px (and force every section into a narrow column). */
.entry-content:not(.alignfull):not(.alignwide),
.wp-block-post-content:not(.alignfull):not(.alignwide) {
  max-width: 68ch;
  margin-left: auto;
  margin-right: auto;
}

/* Code blocks — Plex Mono with subtle surface */
:where(pre, code, kbd, samp) {
  font-family: var(--wp--preset--font-family--plex-mono);
}
:where(pre.wp-block-code, .wp-block-code pre) {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--md);
  padding: 1rem 1.25rem;
  font-size: 0.875rem;
  line-height: 1.6;
  overflow-x: auto;
}
:where(:not(pre) > code) {
  background: var(--surface-2);
  padding: 0.125rem 0.375rem;
  border-radius: var(--wp--custom--radius--sm);
  font-size: 0.875em;
  color: var(--ink);
}

/* Table — modest defaults so blog post tables don't look unstyled */
.wp-block-table table {
  border-collapse: collapse;
  width: 100%;
}
.wp-block-table th,
.wp-block-table td {
  border-bottom: 1px solid var(--border);
  padding: 0.5rem 0.75rem;
  text-align: left;
}
.wp-block-table th {
  background: var(--surface-2);
  font-weight: 600;
}

/* Quote — subtle, brand-tinted left border */
.wp-block-quote {
  border-left: 3px solid var(--brand);
  padding-left: 1.25rem;
  font-family: var(--wp--preset--font-family--plex-serif);
  font-style: italic;
  color: var(--ink);
}
.wp-block-quote cite {
  display: block;
  margin-top: 0.5rem;
  font-style: normal;
  font-family: var(--wp--preset--font-family--plex-sans);
  font-size: 0.875rem;
  color: var(--ink-muted);
}

/* Image — never overflow, respect aspect ratio set by width/height */
.wp-block-image img {
  max-width: 100%;
  height: auto;
  border-radius: var(--wp--custom--radius--md);
}

/* No-bullet list style — used in footer column lists */
.is-style-no-bullet {
  list-style: none;
  padding-left: 0;
  margin-left: 0;
}
.is-style-no-bullet li::before {
  content: none;
}

/* Site nav — primary header navigation. Inline links instead of
   wp:navigation block to avoid the empty-nav-post bug in template
   parts. */
.site-nav {
  display: inline-flex;
  align-items: center;
  position: relative;
}
.site-nav__links {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--wp--preset--spacing--30);
}
.site-nav__links a {
  color: var(--ink);
  text-decoration: none;
  font-weight: 500;
  transition: color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.site-nav__links a:hover,
.site-nav__links a:focus-visible,
.site-nav__links a[aria-current="page"] {
  color: var(--brand);
}

/* Kontakt CTA — pill button. Default state is a brand-soft chip; swaps
   to solid brand on hover/focus/active so the primary action keeps
   gravity even when sitting next to the same-coloured active link. */
.site-nav__links a.site-nav__cta {
  background: var(--brand-soft);
  color: var(--brand);
  padding: 0.5rem 0.875rem;
  border-radius: 999px;
  font-weight: 600;
  line-height: 1;
  transition:
    background 200ms cubic-bezier(0.4, 0, 0.2, 1),
    color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.site-nav__links a.site-nav__cta:hover,
.site-nav__links a.site-nav__cta:focus-visible,
.site-nav__links a.site-nav__cta[aria-current="page"] {
  background: var(--brand);
  color: var(--surface);
}

/* Portfolio language switcher — pll_the_languages() wrapped in our own
   block. Visual parity with the dark-mode toggle: Plex Mono uppercase
   small chip-style links. */
.portfolio-lang-switcher,
.wp-block-portfolio-core-lang-switcher {
  display: inline-flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.8125rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.portfolio-lang-switcher li {
  margin: 0;
  padding: 0;
}
.portfolio-lang-switcher a {
  color: var(--ink-muted);
  text-decoration: none;
  padding: 0.25rem 0.5rem;
  border-radius: var(--wp--custom--radius--sm);
  transition: color 200ms cubic-bezier(0.4, 0, 0.2, 1), background 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.portfolio-lang-switcher a:hover {
  color: var(--ink);
  background: var(--surface-2);
}
.portfolio-lang-switcher .current-lang a,
.portfolio-lang-switcher .current-lang {
  color: var(--ink);
  font-weight: 600;
}

/* Header utility cluster — wraps lang-switcher + dark-toggle in a
   single chip so they read as utilities, not nav. surface-2 fill +
   soft border separates them visually from the link rail to the
   left, matching the Linear/Vercel-style header pattern. */
.site-header__utils {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.1875rem 0.375rem;
}
/* Compact the dark toggle inside the chip — the standalone 2.25rem
   square would dominate the cluster. Lang-switcher links keep their
   own padding; we just neutralise their hover background so the chip
   reads as one shape. */
.site-header__utils .portfolio-dark-toggle {
  width: 1.875rem;
  height: 1.875rem;
  border-radius: 999px;
}
.site-header__utils .portfolio-dark-toggle:hover {
  background: var(--surface-3, var(--border));
  border-color: transparent;
}
.site-header__utils .portfolio-lang-switcher a:hover {
  background: var(--surface-3, var(--border));
}
.site-header__utils .portfolio-lang-switcher a {
  border-radius: 999px;
}

/* ----------------------------------------------------------------------
   Header terminal — typewriter chip rendered between the site title and
   the nav cluster. Plex Mono on a surface-2 pill matches the utils chip
   (lang + dark toggle) on the right edge so the header reads as three
   balanced segments: wordmark · terminal · controls.
   The IIFE in parts/header.html cycles the text content; this block
   only supplies chrome. Hidden below 1100px — phones don't need the
   gimmick.
   ---------------------------------------------------------------------- */
.header-term {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  max-width: 22rem;
  padding: 0.25rem 0.75rem;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--ink-muted);
  white-space: nowrap;
  overflow: hidden;
}
.header-term__prompt {
  color: var(--brand);
  font-weight: 600;
  flex-shrink: 0;
}
.header-term__text {
  color: var(--ink-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.header-term__cursor {
  color: var(--brand);
  font-weight: 600;
  animation: header-term-blink 1.1s steps(1) infinite;
}
@keyframes header-term-blink {
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0; }
}
@media (max-width: 1100px) {
  .header-term { display: none; }
}

/* ----------------------------------------------------------------------
   Usługi mega-dropdown — single absolute panel anchored to the trigger
   on desktop (≥769px); inline accordion in the mobile drawer (rules in
   the @media block at the bottom of the site-nav section).
     - Trigger is button-reset so it matches the surrounding <a> link
       typography (Plex Sans 500, ink → brand on hover/active, animated
       brand underline shared with the rest of the nav rail).
     - Chevron rotates 180° on aria-expanded="true".
     - Panel is a surface card with a 3-column grid of pillars. Each
       pillar links to its landing page (/aplikacje, /oprogramowanie,
       /wdrozenie-ksef); optional sublist links to deep sub-pages
       below.
   ---------------------------------------------------------------------- */
.site-nav__services-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.site-nav__services-trigger {
  appearance: none;
  background: transparent;
  border: 0;
  margin: 0;
  padding: 0;
  font: inherit;
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  transition: color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.site-nav__services-trigger:hover,
.site-nav__services-trigger:focus-visible,
.site-nav__services-trigger.is-active,
.site-nav__services-trigger[aria-expanded="true"] {
  color: var(--brand);
}
.site-nav__chevron {
  display: inline-block;
  font-size: 0.75em;
  line-height: 1;
  transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.site-nav__services-trigger[aria-expanded="true"] .site-nav__chevron {
  transform: rotate(180deg);
}

.services-panel {
  position: absolute;
  top: calc(100% + 0.75rem);
  right: 0;
  z-index: 120;
  min-width: 36rem;
  max-width: min(46rem, calc(100vw - 2rem));
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--md, 8px);
  box-shadow: var(--shadow-card-lifted);
  padding: var(--wp--preset--spacing--30);
  animation: services-panel-fade 160ms cubic-bezier(0.4, 0, 0.2, 1);
}
.services-panel[hidden] {
  display: none;
}
@keyframes services-panel-fade {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.services-panel__cols {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--wp--preset--spacing--30);
  list-style: none;
  margin: 0;
  padding: 0;
}
.services-panel__cols > li::before { content: none; }
.services-panel__col {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: var(--wp--preset--spacing--20);
  border-radius: var(--wp--custom--radius--sm, 4px);
  transition: background 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.services-panel__col:hover,
.services-panel__col:focus-within {
  background: var(--surface-2);
}
.services-panel__col.is-active {
  background: var(--brand-soft);
}
.services-panel__pillar {
  display: flex;
  align-items: flex-start;
  gap: 0.625rem;
  text-decoration: none;
  color: var(--ink);
  font-weight: 600;
}
.services-panel__pillar:hover,
.services-panel__pillar:focus-visible {
  color: var(--brand);
}
.services-panel__pillar-icon {
  font-size: 1.5rem;
  line-height: 1;
  flex-shrink: 0;
}
.services-panel__pillar-text {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
}
.services-panel__pillar-name {
  font-size: 0.9375rem;
  line-height: 1.2;
}
.services-panel__pillar-blurb {
  font-size: 0.8125rem;
  font-weight: 400;
  color: var(--ink-muted);
  line-height: 1.3;
}
.services-panel__col.is-active .services-panel__pillar-name {
  color: var(--brand);
}
.services-panel__sublist {
  list-style: none;
  margin: 0.25rem 0 0 2.125rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}
.services-panel__sublist li::before { content: none; }
.services-panel__sublist a {
  display: block;
  padding: 0.25rem 0;
  font-size: 0.8125rem;
  color: var(--ink-muted);
  text-decoration: none;
  transition: color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.services-panel__sublist a:hover,
.services-panel__sublist a:focus-visible,
.services-panel__sublist a[aria-current="page"] {
  color: var(--brand);
}

/* Brand dot before the wordmark — small filled circle in the brand
   hue, sits 0.5rem to the left of the site-title text. Anchors the
   left side of the header without a logo asset. Footer wordmark is
   excluded (its scope is .site-footer ...). */
header.wp-block-template-part .wp-block-site-title,
.wp-site-blocks > header.wp-block-group .wp-block-site-title {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
header.wp-block-template-part .wp-block-site-title::before,
.wp-site-blocks > header.wp-block-group .wp-block-site-title::before {
  content: '';
  display: inline-block;
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 50%;
  background: var(--brand);
  flex-shrink: 0;
}

/* Sticky frosted-glass header — Linear-influenced.
   position: sticky pins the header to the top once the viewport scrolls
   past it. backdrop-filter blurs the surface that scrolls under, while
   --header-bg supplies a translucent tint that picks up the right
   surface color in either mode via light-dark(). Border stays soft
   (low alpha) so the header reads as floating on top of the canvas,
   not glued to it. */
/* The outer .wp-block-template-part wrapper is the actual <header> in
   document flow (sibling of <main>); the inner .wp-block-group is its
   only child. Sticky must live on the outer one — otherwise its sticky
   range is clamped to the outer's height and detaches almost
   immediately. We style both selectors so the design holds whichever
   element WP renders in your build. */
header.wp-block-template-part,
.wp-site-blocks > header.wp-block-group {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--header-bg);
  backdrop-filter: blur(12px) saturate(180%);
  -webkit-backdrop-filter: blur(12px) saturate(180%);
  border-bottom: 1px solid var(--header-border);
  transition:
    background 200ms cubic-bezier(0.4, 0, 0.2, 1),
    border-color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* Inner header (group inside the template-part wrapper) stays
   transparent — the frosted glass lives on the outer wrapper. */
header.wp-block-template-part > .wp-block-group {
  background: transparent;
  border-bottom: 0;
}

/* Fallback for browsers without backdrop-filter (Firefox <103, ~4%
   global by 2026). Solid surface — no blur, layout intact. */
@supports not (backdrop-filter: blur(1px)) {
  header.wp-block-template-part,
  .wp-site-blocks > header.wp-block-group {
    background: var(--surface);
  }
}

/* Mobile — backdrop-filter is GPU-expensive on low-end Android.
   Drop the blur, keep sticky behaviour and a solid surface. */
@media (max-width: 768px) {
  header.wp-block-template-part,
  .wp-site-blocks > header.wp-block-group {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: var(--surface);
  }
}

/* ----------------------------------------------------------------------
   Alternating section surfaces — replaces the (computed-invisible) bloom-
   divider rhythm from Tier 3 (research §3.2 confirmed the gradient-bloom
   token resolved to invisible against the cool-grey surface). Reads as
   "no-tint → tinted → no-tint → tinted" down the page, surfacing the
   section structure without any new tokens.

   Home rhythm per templates/front-page.html:
     hero, stats, projects, services, trust-strip, process, testimonials,
     about, contact

   Pattern paints projects, trust-strip, testimonials so the rhythm
   reads strictly none/none/s2/none/s2/none/s2/none/contact-chrome
   (Tier 3.15.2 fix — was projects/process/testimonials, which produced
   adjacent s2 rows and left trust-strip floating without a backdrop
   anchor). About stays neutral (text-driven), hero keeps its own
   gradient backdrop. .contact-section is intentionally NOT included
   here — it already paints surface-2 + a 16px rounded border via
   style.css:721 and the contact-cta.php pattern wrapper. Re-applying
   surface-2 would be a no-op, but adding the border-block hairlines
   below would cut a square line through its rounded card.

   The body bg is var(--surface) so any non-tinted section reveals the
   page surface as the "no-tint" rhythm row.
   ---------------------------------------------------------------------- */
.wp-site-blocks > main > .alignwide { position: relative; }

/* Tinted sections paint their background via a ::before pseudo that
   bleeds out to the viewport edges. Section content keeps its alignwide
   layout (1280px max, root-padded) — only the paint goes wide. The
   `isolation: isolate` on the section creates a stacking context so the
   z-index:-1 pseudo doesn't slip behind the body bg.

   Generic opt-in: add className `is-style-section-bleed` to any group
   to get the same effect. Override surface per-section by setting
   `--section-bg` / `--section-border` on a more specific selector. */
.projects-section,
.use-cases-section,
.trust-strip,
.testimonials-section,
.is-style-section-bleed {
  position: relative;
  isolation: isolate;
}
.projects-section::before,
.use-cases-section::before,
.trust-strip::before,
.testimonials-section::before,
.is-style-section-bleed::before {
  content: "";
  position: absolute;
  inset-block: 0;
  left: calc(50% - 50vw);
  width: 100vw;
  background: var(--section-bg, var(--surface-2));
  border-top: var(--section-border, 1px solid var(--border));
  border-bottom: var(--section-border, 1px solid var(--border));
  z-index: -1;
  pointer-events: none;
}

/* Required so the 100vw bleed doesn't introduce a horizontal scrollbar
   on pages where the document is narrower than 100vw (the vertical
   scrollbar reserves ~16px). `clip` is preferred over `hidden` — it
   doesn't establish a new scroll container, so the sticky header above
   (style.css:290) keeps pinning correctly. */
html, body {
  overflow-x: clip;
}

/* ----------------------------------------------------------------------
   Site footer — subtle elevated band. Background lifts one step from
   page surface to var(--surface-3) so the footer reads as a distinct
   rhythm row after the contact-card above, without the inverted-dark
   contrast of a pure dark band. Borders use --border-strong (one step
   firmer than the rhythm-row hairlines) so the footer feels anchored.

   Bleed comes free from .is-style-section-bleed (the shared mechanism);
   the rules below only override surface tokens and tune interior
   typography for the slightly elevated background.
   ---------------------------------------------------------------------- */
.site-footer {
  --section-bg: var(--surface-3);
  --section-border: 1px solid var(--border-strong);
}

/* Column eyebrows — calm down against the lighter surface so they read
   as labels not headlines. */
.site-footer .is-style-eyebrow {
  color: var(--ink-faint);
  margin-bottom: var(--wp--preset--spacing--20);
}

/* Link lists — drop underlines, lift on hover toward brand-strong. */
.site-footer a {
  color: var(--ink-muted);
  text-decoration: none;
  transition: color var(--wp--custom--transition--fast);
}
.site-footer a:hover,
.site-footer a:focus-visible {
  color: var(--brand-strong);
}

/* Wordmark size — between body and section H2 so the footer brand
   reads but doesn't compete with anything above. */
.site-footer .wp-block-site-title {
  font-size: 1.125rem;
  letter-spacing: -0.01em;
}

/* Closing rule — half-opacity hairline, just a beat of breath above
   the copyright. */
.site-footer .wp-block-separator {
  border-color: var(--border);
  opacity: 0.5;
}

/* Copyright line — recede further. Mono caps already declared by
   `.is-style-mono`; here we just dim and tighten letter-spacing. */
.site-footer .is-style-mono {
  color: var(--ink-faint);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
}

/* Section eyebrow — numbered "01 · Wybrane projekty" headline cap.
   The numeral lives in a brand-soft pill; the label sits next to it.
   Both spans inside a single paragraph so the structure is screen-reader
   friendly without ::before content tricks. */
.section-num {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

/* Tighten the gap between the eyebrow and whatever follows it — the H2,
   or a flex group containing the H2 + a side link. Without this, WP's
   constrained-layout blockGap (~1.5rem) leaves them reading as two
   separate stacked elements; 0.25rem groups them as a single title
   block. The sibling selector beats WP's :where() blockGap cleanly. */
.section-num + * {
  margin-block-start: 0.25rem;
}
.section-num > span:first-child {
  display: inline-block;
  background: var(--brand-soft);
  color: var(--brand);
  padding: 0.125rem 0.5rem;
  border-radius: var(--wp--custom--radius--sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.section-num > span:last-child {
  color: var(--ink-muted);
}

/* ----------------------------------------------------------------------
   Section heading stack — generic alignment fix.

   Direct-child eyebrows (`.section-num`) and headings inside a section
   pattern would otherwise be capped by WP's constrained-layout default
   to content-size (720px) and centered with auto margins. Inside an
   alignwide section (1280px), that leaves them indented ~280px from
   where the alignwide cards / columns / query grid below them start,
   reading as "the title floats in the middle while the cards line up
   against the edge".

   Push them to wide-size so left edges line up with the content
   beneath. Generic via [class*="-section"]; .trust-strip and .hero
   handled explicitly because they don't follow the `-section` suffix
   convention. .contact-section opts out — it's a centered CTA card by
   design.
   ---------------------------------------------------------------------- */
[class*="-section"]:not(.contact-section) > .section-num,
[class*="-section"]:not(.contact-section) > .wp-block-heading,
.trust-strip > .section-num,
.trust-strip > .wp-block-heading,
.hero > .section-num {
  max-width: var(--wp--style--global--wide-size, 1280px);
}

/* Projects-section header strip — H2 + "Wszystkie projekty →" link share
   the same alignwide width as the cards below (Tier 3.14) and a typographic
   baseline rather than a centered vertical alignment (Tier 3.15.5). The
   pattern JSON declares verticalAlignment:baseline but WP core's flex
   layout only honours top/center/bottom — `baseline` is silently dropped.
   This rule pins align-items so the H2 (large type) and the link (small
   type) share their text baselines. Scoped to the projects-section's
   inner alignwide flex group so other alignwide flex groups elsewhere in
   the theme stay on their default center alignment. */
.projects-section > .wp-block-group.alignwide.is-layout-flex {
  align-items: baseline;
}

/* ----------------------------------------------------------------------
   Testimonials — horizontal scroll-snap rail with 3 quote cards. CSS-only
   interaction; no JS, no arrows. Each card is a self-contained article
   with avatar, attribution, and metric chip. Draft cards carry a visible
   amber "DRAFT" badge so the placeholder status is unmistakable until
   real client quotes ship.
   ---------------------------------------------------------------------- */
/* Testimonials rail wrapper — provides relative positioning context for the
   right-edge fade-mask and anchors the alignwide breakout. The wrap itself
   is alignwide so it spans the full 1280 section width; the inner rail
   handles scroll-snap and per-card layout. The terminal color of the
   fade-mask is var(--surface-2) because Task 1.5 paints
   .testimonials-section with surface-2 — the mask must blend into the
   actual section background to read as a fade rather than a hard edge. */
.testimonials__rail-wrap {
  position: relative;
}
.testimonials__rail-wrap::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 64px;
  background: linear-gradient(to right, transparent, var(--surface-2));
  pointer-events: none;
  z-index: 1;
}
.testimonials__rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(280px, 360px);
  gap: var(--wp--preset--spacing--40);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-inline: var(--wp--preset--spacing--40);
  padding-block: var(--wp--preset--spacing--30);
  scroll-padding-inline: var(--wp--preset--spacing--40);
  /* Thin styled scrollbar — visible scroll affordance without dominating */
  scrollbar-width: thin;
  scrollbar-color: var(--brand-soft) transparent;
}
.testimonials__rail::-webkit-scrollbar { height: 8px; }
.testimonials__rail::-webkit-scrollbar-thumb {
  background: var(--brand-soft);
  border-radius: 999px;
}
.testimonials__rail::-webkit-scrollbar-track { background: transparent; }
.testimonials__rail > .quote-card { scroll-snap-align: start; }

.quote-card {
  position: relative;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--lg);
  padding: var(--wp--preset--spacing--50);
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--30);
  min-height: 220px;
  transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1), box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.quote-card::before {
  content: '\201C';
  position: absolute;
  top: 0.5rem;
  left: 1rem;
  font-family: var(--wp--preset--font-family--plex-serif);
  font-size: 4rem;
  line-height: 1;
  color: var(--brand-soft);
  pointer-events: none;
}
.quote-card__text {
  margin: 0;
  padding: 0;
  border: 0;
  font-family: var(--wp--preset--font-family--plex-serif);
  font-size: 1.125rem;
  line-height: 1.5;
  color: var(--ink);
  position: relative;
  z-index: 1;
}
.quote-card__attr {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: auto;
}
.quote-card__avatar {
  width: 40px;
  height: 40px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  background: linear-gradient(135deg, var(--brand) 0%, var(--accent) 100%);
  color: var(--surface);
  font-weight: 600;
  font-size: 0.875rem;
  flex-shrink: 0;
}
.quote-card__name {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--ink);
}
.quote-card__role {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--ink-muted);
}
.quote-card__metric {
  margin-left: auto;
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.75rem;
  color: var(--brand);
  background: var(--brand-soft);
  padding: 0.125rem 0.5rem;
  border-radius: var(--wp--custom--radius--sm);
}
.quote-card[data-status="draft"]::after {
  content: 'DRAFT';
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  color: var(--warning);
  background: color-mix(in oklch, var(--warning) 18%, var(--surface));
  padding: 0.125rem 0.375rem;
  border-radius: var(--wp--custom--radius--sm);
}

/* ----------------------------------------------------------------------
   Trust strip — 7 grayscale tech logos in a centered horizontal row.
   currentColor + grayscale filter keeps each SVG single-color and theme-
   aware; hover desaturates back to full color. Caption sits above the
   row in mono caps.
   ---------------------------------------------------------------------- */
.trust-strip__caption {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-muted);
  text-align: center;
  margin: 0 0 var(--wp--preset--spacing--40);
}
.trust-strip__logos {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--wp--preset--spacing--50);
}
.trust-strip__logos li {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.875rem;
  color: var(--ink-muted);
  filter: grayscale(1);
  opacity: 0.7;
  transition: filter 200ms cubic-bezier(0.4, 0, 0.2, 1), opacity 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.trust-strip__logos li:hover {
  filter: grayscale(0);
  opacity: 1;
}
.trust-strip__logos svg {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

/* ----------------------------------------------------------------------
   Service-card additions — chip + eyebrow with pip + outcome bullets
   + link footer + alternating inverted-checker rotation. Uses
   nth-child(even) to flip cards 2 + 4 to the inverted surface so the
   row reads as a checker rhythm instead of all-white.
   ---------------------------------------------------------------------- */
.service-card__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--wp--preset--spacing--30);
}
.service-card__chip {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.125rem 0.5rem;
  border-radius: var(--wp--custom--radius--sm);
  background: var(--brand-soft);
  color: var(--brand);
}
.service-card__outcomes {
  list-style: none;
  padding: 0;
  margin: var(--wp--preset--spacing--30) 0 0;
  display: grid;
  gap: 0.375rem;
}
.service-card__outcomes li {
  position: relative;
  padding-left: 1.25rem;
  font-size: 0.875rem;
  color: var(--ink-muted);
  line-height: 1.5;
}
.service-card__outcomes li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.5rem;
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--brand);
}
.service-card__link {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  margin-top: var(--wp--preset--spacing--40);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--brand);
  text-decoration: none;
}
.service-card__link:hover { text-decoration: underline; }

/* ----------------------------------------------------------------------
   Use-case card additions — chip-row of mono stack pills + indigo
   save-metric footer. Reuses .is-style-card for surface/border/radius
   and .eyebrow eyebrow--brand for the category label, so the only
   bespoke CSS is the chip-row layout and save-metric line. The chip
   visual matches the project-card stack-term chip (style.css:1175) —
   brand-soft bg, brand text, mono uppercase — so all "stack term"
   pills across the theme share one vocabulary.
   ---------------------------------------------------------------------- */
.use-case-card__chips {
  list-style: none;
  padding: 0;
  margin: var(--wp--preset--spacing--30) 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
}
.use-case-card__chips li {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--brand);
  background: var(--brand-soft);
  padding: 0.125rem 0.5rem;
  border-radius: var(--wp--custom--radius--sm);
  white-space: nowrap;
}
.use-case-card__save {
  margin: var(--wp--preset--spacing--40) 0 0;
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.8125rem;
  color: var(--brand);
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}
.use-case-card__save > span[aria-hidden="true"] {
  color: var(--brand);
  font-weight: 600;
}

/* Eyebrow with colored pip — alongside is-style-eyebrow, used by new
   patterns. The pip color rotates per modifier class. */
.eyebrow {
  font-family: var(--wp--preset--font-family--plex-mono);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 0.75rem;
  color: var(--ink-muted);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 var(--wp--preset--spacing--20);
}
.eyebrow__pip { font-size: 0.625rem; line-height: 1; }
.eyebrow--brand   .eyebrow__pip { color: var(--brand); }
.eyebrow--accent  .eyebrow__pip { color: var(--accent); }
.eyebrow--success .eyebrow__pip { color: var(--success); }

/* M5 — inverted-checker rotation. Cards 2 + 4 (Web + AI) flip to the
   inverted surface, keeping the row from reading as a uniform light
   row. surface-inverted and ink-on-inverted auto-flip in dark mode. */
.service-card:nth-child(even) {
  background: var(--surface-inverted);
  color: var(--ink-on-inverted);
  border-color: var(--surface-inverted);
}
.service-card:nth-child(even) p,
.service-card:nth-child(even) .service-card__outcomes li,
.service-card:nth-child(even) .eyebrow {
  color: color-mix(in oklch, var(--ink-on-inverted) 78%, transparent);
}
.service-card:nth-child(even) h3 { color: var(--ink-on-inverted); }
.service-card:nth-child(even) .service-card__link { color: var(--brand-soft); }
.service-card:nth-child(even) .card-deco circle { fill: color-mix(in oklch, var(--brand) 30%, transparent); }

/* ----------------------------------------------------------------------
   About summary — 2-col layout with italic-serif pull-quote on the left
   and a gradient-initials "M" monogram avatar on the right. Avatar uses
   a 135deg brand→accent gradient (second deliberate teal moment per A6).
   Stacks on mobile (≤859px) with the avatar capped at 160px.
   ---------------------------------------------------------------------- */
.about__pull-quote {
  font-family: var(--wp--preset--font-family--plex-serif);
  font-size: clamp(1.25rem, 2.5vw, 1.75rem);
  line-height: 1.4;
  color: var(--ink);
  margin: 0 0 var(--wp--preset--spacing--40);
  font-style: italic;
  font-weight: 400;
  max-width: 28ch;
}
/* Display variant — full-row pull-quote that hangs above the 60/40 about
   split (Linear's "display-emphasis-above-split" pattern). Larger type,
   wider max-width so it fills the alignwide section without text-wall
   density. Used in patterns/about-summary.php directly under the
   section-num eyebrow, before the wp:columns block. */
.about__pull-quote--display {
  font-size: clamp(1.75rem, 3.5vw, 2.5rem);
  line-height: 1.3;
  max-width: 60ch;
  margin: 0 0 var(--wp--preset--spacing--50);
  color: var(--ink);
}
.about__avatar {
  width: clamp(160px, 24vw, 240px);
  aspect-ratio: 1;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--brand) 0%, var(--accent) 100%);
  display: grid;
  place-items: center;
  margin: 0 auto;
  box-shadow: var(--shadow-card-lifted);
}
.about__avatar > span {
  font-family: var(--wp--preset--font-family--plex-serif);
  font-size: clamp(4rem, 8vw, 6rem);
  font-weight: 700;
  color: var(--surface);
  line-height: 1;
  letter-spacing: -0.02em;
}
@media (max-width: 859px) {
  .about__avatar { max-width: 160px; }
}

/* ----------------------------------------------------------------------
   Contact CTA bookend — closes the page with the same status pill the
   hero opens with. Bloom backdrop scoped inside the rounded card via
   ::after + overflow: hidden (so the bloom doesn't bleed past the
   border). Uses ::after instead of ::before to avoid clashing with
   the outer-section bloom selector list. kbd chip is teal-tinted —
   third deliberate teal accent moment per A6.
   ---------------------------------------------------------------------- */
.contact-section {
  position: relative;
  overflow: hidden;
  background: var(--surface-2);
  isolation: isolate;
}
.contact-section::after {
  content: '';
  position: absolute;
  inset: -40px 0 auto 0;
  height: 200px;
  background: var(--gradient-bloom);
  opacity: 0.8;
  pointer-events: none;
  z-index: -1;
}
.contact-badges {
  display: flex;
  justify-content: center;
  margin: 0 0 var(--wp--preset--spacing--30);
}
.contact-section__fineprint {
  font-style: italic;
}

/* Contact-page honeypot — visually off-screen but reachable by bots and
   ignored by humans + screen-readers (aria-hidden="true" on container). */
.pc-form__honeypot {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
.kbd-hint kbd,
kbd {
  display: inline-block;
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.75rem;
  padding: 0.125rem 0.4rem;
  background: color-mix(in oklch, var(--accent) 18%, transparent);
  border: 1px solid color-mix(in oklch, var(--accent) 50%, transparent);
  border-radius: var(--wp--custom--radius--sm);
  color: var(--accent);
  box-shadow: 0 1px 0 0 color-mix(in oklch, var(--accent) 35%, transparent);
  margin-left: 0.4rem;
  vertical-align: 0.05em;
}
.kbd-hint:focus-visible {
  box-shadow: var(--ring-focus-strong);
  outline: none;
}

/* ----------------------------------------------------------------------
   Hero — Variant A services-grid composition (sketch 001 winner). The
   menu IS the hero: tighter ~7-word H1, mono subline of guarantees, two
   centered CTAs, then a 4-tile service grid (4-col at >=720px, 2-col at
   <720px), with status pills bottoming out the column. Code-card was
   dropped — in a services-grid layout the tiles are themselves the
   hero-anchor visual, and a competing card halves the tiles' attention
   budget. Halo + dot-grid background carry over from prior iteration;
   second halo blob retuned to `at 70% 70%` to land behind the tile row
   (was 80% — too low when the column ends with pills, not a card).
   Reference: agency.dev, rauno.me.
   ---------------------------------------------------------------------- */
.hero {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--wp--preset--spacing--50);
  overflow: hidden;
  /* alignfull strips root padding from the block so the dot-grid +
     halo backgrounds extend edge-to-edge across the viewport. We
     re-apply root-padding on the inline axis so the inner 920px
     shell still gets breathing room on viewports between 920px and
     the edge. Content stays inside; background bleeds out. */
  padding-inline: var(--wp--custom--root-padding, clamp(1rem, 4vw, 4rem));
  /* Dot grid as a subtle textural background, tied to --border so it
     flips with the theme. 24px x 24px lattice, 1px dot. */
  background-image: radial-gradient(circle at 1px 1px, var(--border) 1px, transparent 0);
  background-size: 24px 24px;
}

/* home-pillars sits directly beneath the hero. The default 1px hairline
   from .is-style-section-bleed reads as a faint line at the boundary,
   which is fine in isolation but underweight given the hero's halo+grid
   visual density. Bump the top border one tier (border-strong, 2px) so
   the transition reads as an intentional section break rather than a
   subtle accident. The surface-2 bleed background already provides a
   color-band break; the firmer border is the punctuation. */
.home-pillars-section.is-style-section-bleed {
  --section-border: 2px solid var(--border-strong);
}

/* ----------------------------------------------------------------------
   Home pillars grid — 5 service-pillar cards (3 live + 2 "Wkrótce")
   funneling home traffic into the SEO-architecture pillar pages.
   Layout: auto-fit minmax(280px, 1fr) so 5 items reflow naturally
   (3+2 at 1280px, 2+2+1 at tablet, 1-col at phone). Each card is a
   full-card anchor with eyebrow → title (+ optional Wkrótce chip)
   → lede → CTA. Soon cards get muted treatment so live pillars
   carry the visual weight.
   ---------------------------------------------------------------------- */
.home-pillars__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.25rem;
  list-style: none;
  margin: var(--wp--preset--spacing--40) 0 0;
  padding: 0;
}
.home-pillars__card {
  display: block;
  list-style: none;
  margin: 0;
  padding: 0;
}
.home-pillars__link {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 1.75rem 1.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--md);
  text-decoration: none;
  color: inherit;
  transition: background 200ms ease, border-color 200ms ease, transform 200ms ease, box-shadow 200ms ease;
}
.home-pillars__link:hover {
  background: var(--surface-2);
  border-color: var(--brand);
  transform: translateY(-2px);
  box-shadow: var(--shadow-card-lifted);
  text-decoration: none;
}
.home-pillars__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-bottom: 1rem;
  border-radius: var(--wp--custom--radius--sm);
  background: var(--brand-soft);
  font-size: 1.5rem;
  line-height: 1;
}
.home-pillars__eyebrow {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--brand);
  font-weight: 500;
  margin: 0 0 0.5rem;
  line-height: 1.4;
}
.home-pillars__title {
  font-family: var(--wp--preset--font-family--plex-sans);
  font-weight: 600;
  font-size: 1.125rem;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0 0 0.75rem;
  line-height: 1.3;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}
.home-pillars__pill {
  display: inline-flex;
  align-items: center;
  padding: 0.125rem 0.5rem;
  border-radius: var(--wp--custom--radius--pill);
  background: var(--surface-3);
  color: var(--ink-muted);
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border: 1px solid var(--border);
}
.home-pillars__lede {
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ink-muted);
  margin: 0 0 1rem;
  flex: 1;
}
.home-pillars__cta {
  font-family: var(--wp--preset--font-family--plex-sans);
  font-weight: 500;
  font-size: 0.9375rem;
  color: var(--brand);
  transition: transform 200ms ease;
  display: inline-block;
}
.home-pillars__link:hover .home-pillars__cta {
  transform: translateX(2px);
}
/* Soon cards — muted so live pillars carry the visual weight */
.home-pillars__card--soon .home-pillars__link {
  background: var(--surface);
  opacity: 0.85;
}
.home-pillars__card--soon .home-pillars__icon {
  background: var(--surface-3);
  filter: saturate(0.5);
}
.home-pillars__card--soon .home-pillars__eyebrow {
  color: var(--ink-faint);
}
.home-pillars__card--soon .home-pillars__cta {
  color: var(--ink-muted);
}
.home-pillars__card--soon .home-pillars__link:hover {
  opacity: 1;
  border-color: var(--border-strong);
  transform: translateY(-1px);
}

/* Halo — two indigo blobs at low opacity behind the hero content.
   ::before sits behind content (z-index: 0 on parent stack) but still
   above the dot-grid. Second blob anchors at 70% 70% so it lands
   behind the tile row (Variant A's primary visual mass below the
   headline+CTAs), not below it. */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 60% 50% at 30% 35%, var(--halo-1), transparent 70%),
    radial-gradient(ellipse 40% 40% at 70% 70%, var(--halo-2), transparent 70%);
  z-index: 0;
  pointer-events: none;
}
.hero > * {
  position: relative;
  z-index: 1;
}

/* Centered single-column shell that holds the Variant A composition.
   max-width 920px reads as a focused funnel (vs the prior 1280px wide
   text+visual split); margin-inline:auto centres it inside the alignwide
   parent; text-align:center pulls the eyebrow + h1 + subline + CTAs +
   pills into one optical axis. Tiles override the alignment to left
   (cards read left-aligned by convention). */
.hero__inner {
  max-width: 920px;
  margin-inline: auto;
  text-align: center;
}

.hero__eyebrow-row {
  /* The flex layout itself is set by the block-supports JSON
     (justifyContent:center). This rule just absorbs the inline-svg
     vertical-rhythm tweak the prior hero relied on. */
  justify-content: center;
}

.hero h1 {
  /* Tightened headline letter-spacing per Linear. */
  letter-spacing: -0.02em;
  /* Variant A's H1 is shorter (~7 words: "Buduję aplikacje,
     oprogramowanie i wdrażam KSeF.") so 18ch (~720px) gives a
     three-line composition at 1440 without forcing a wider measure
     than the 920px shell. text-wrap:balance + hyphens:manual stays
     in case a translation lands a longer string later. */
  text-wrap: balance;
  hyphens: manual;
  max-width: 18ch;
  margin-inline: auto;
}

/* Mono subline of guarantees — replaces the prior prose lede. Four
   chips separated by faint dot separators: MVP timeline, fixed-price,
   IP-ownership, faktura VAT. Mono+small reads as a "specifications"
   strip, distinct from headline rhetoric and from the prose lede the
   prior layout used. */
.hero__subline {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.9375rem;
  color: var(--ink-muted);
  letter-spacing: 0.02em;
}
.hero__subline .sep {
  color: var(--ink-faint);
  margin-inline: 0.5rem;
}

/* Centered CTA row — actual flex layout applied by the block-supports
   JSON on the wp:buttons block; this rule is a defensive fallback in
   case the wrapper renders the buttons stacked. */
.hero__cta-row {
  justify-content: center;
}

/* Tile grid — 4 abreast at >=720px, 2 abreast below. The grid lives
   directly beneath the CTAs and is the dominant visual mass of the
   hero. Each tile is a full-card link (a.tile) with icon + title +
   one-line desc + arrow glyph in the top-right. */
.hero__tiles {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
  margin-top: var(--wp--preset--spacing--20);
  text-align: left;
}

.tile {
  display: block;
  position: relative;
  padding: 1.5rem 1.25rem;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--md);
  text-decoration: none;
  transition: background 200ms ease, border-color 200ms ease, transform 200ms ease;
}
.tile:hover {
  background: var(--surface-3);
  border-color: var(--brand);
  transform: translateY(-2px);
  text-decoration: none;
}
.tile__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  margin-bottom: 0.875rem;
  border-radius: var(--wp--custom--radius--sm);
  background: var(--brand-soft);
  color: var(--brand);
}
.tile__title {
  font-family: var(--wp--preset--font-family--plex-sans);
  font-weight: 600;
  font-size: 1.0625rem;
  color: var(--ink);
  margin: 0 0 0.25rem;
  letter-spacing: -0.01em;
}
.tile__desc {
  font-size: 0.8125rem;
  color: var(--ink-muted);
  margin: 0;
  line-height: 1.5;
}
.tile__arrow {
  position: absolute;
  top: 1.5rem;
  right: 1.25rem;
  color: var(--ink-faint);
  font-family: var(--wp--preset--font-family--plex-mono);
  transition: color 200ms ease, transform 200ms ease;
}
.tile:hover .tile__arrow {
  color: var(--brand);
  transform: translate(2px, -2px);
}

/* Pill row — centered under the tile grid as the closing trust-strip
   beat. .hero-badges base rule already handles spacing/wrap; this
   override only re-centres it inside the .hero__inner column. */
.hero__pill-row {
  justify-content: center;
  margin-top: var(--wp--preset--spacing--20);
}

/* Mobile reflow — 2-col tiles, smaller H1, stacked CTAs. 720px is
   the same breakpoint the sketch source uses; matches the existing
   theme's other "switch to single/double column" thresholds. */
@media (max-width: 720px) {
  .hero__tiles {
    grid-template-columns: repeat(2, 1fr);
  }
  .hero__cta-row {
    flex-direction: column;
    align-items: stretch;
  }
  .hero__cta-row .wp-block-button,
  .hero__cta-row .wp-block-button__link {
    width: 100%;
    justify-content: center;
    text-align: center;
  }
}

/* ----------------------------------------------------------------------
   Iteration loop visualization — modern conic-gradient progress arc
   sweeping clockwise (brand fills, brand-soft trail) with five phase
   nodes (Rozmowa → Plan → Build → Demo → Feedback) absolutely positioned
   on the ring via CSS custom-prop angle math. The arc accumulates over
   each 14s cycle (--p: 0deg → 360deg via @property) instead of just
   rotating a dot — semantically closer to "every demo feeds the next
   conversation." A centre phase-narrator and a synced right-side detail
   panel ride the same negative-delay schedule (0s, -11.2s, -8.4s,
   -5.6s, -2.8s for phases 1-5).
   The whole section sits inside a surface-3 bleed band so the diagram
   anchors its own rhythm row between Process and Testimonials.
   No JS, no framework — pure CSS + @property interpolation.
   ---------------------------------------------------------------------- */

/* Section-level surface override — drives the .is-style-section-bleed
   ::before paint that the iteration-section opts into via its className.
   Same mechanism the footer uses; surface-3 distinguishes this row from
   the surface-2 rhythm rows above and below. */
.iteration-section {
  --section-bg: var(--surface-3);
  --section-border: 1px solid var(--border-strong);
}

/* Two-column shell — ring on the left, synchronized detail panel on
   the right. flex with wrap + flex-basis 320 means the columns stack
   automatically on viewports narrower than ~720px (no media query
   needed for this layout switch). align-items: center so the shorter
   detail panel vertically centres against the taller ring.
   Retained for backwards-compat / future use; the live pattern
   currently uses the .iteration-loop--row variant below. */
.iteration-loop--split {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--wp--preset--spacing--50);
  margin-block-start: var(--wp--preset--spacing--40);
}

/* Row variant — ring as a top-of-section accent (smaller), five phase
   cards in one horizontal row directly below. All five phases visible
   at once; the 14s cycle reattaches as a brand-coloured top stripe
   that travels card-by-card on the same negative-delay schedule used
   by the ring arc and node pulses. Wraps cleanly to 2-col then 1-col
   on smaller viewports.
   Selected over .iteration-loop--split because the cycling-one-at-a-
   time panel hid 4/5 phases from sighted users — the row variant lets
   visitors scan the whole process at a glance while keeping the
   "now" indicator the cycle provides. */
.iteration-loop--row {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--wp--preset--spacing--40);
  margin-block-start: var(--wp--preset--spacing--40);
}

/* Shrink the ring inside the row variant — it's now a section accent
   rather than the dominant element. Outer node labels are redundant
   (cards below carry phase names), so hide them; arc + node pulses
   keep running on the same 14s clock. */
.iteration-loop--row .iteration-ring {
  --r: clamp(80px, 9vw, 110px);
  --thickness: 7px;
  --label-offset: 14px;
}
.iteration-loop--row .iteration-ring__label { display: none; }

/* Cards: 5 abreast on desktop, auto-fit minmax on tablet, single
   column on phone. The grid replaces the previous absolutely-stacked
   cycling panel, so all five items render in-flow.
   `flex: initial` resets the legacy `flex: 1 1 320px` from the parent
   .iteration-detail rule — in the column-flex .iteration-loop--row
   shell that flex-basis was clamping the <ol> to a 320px height and
   crushing every card to ~155px (and to ~64px when the grid stacks
   to 1-col on mobile). With flex: initial the <ol> sizes to its
   grid content like any normal block. */
.iteration-loop--row .iteration-detail {
  width: 100%;
  min-height: 0;
  flex: initial;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--wp--preset--spacing--30);
}
@media (max-width: 1100px) {
  .iteration-loop--row .iteration-detail {
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  }
}
@media (max-width: 600px) {
  .iteration-loop--row .iteration-detail {
    grid-template-columns: 1fr;
  }
}

/* Override the cycling absolute layout from .iteration-detail__item:
   each card sits in its grid cell, permanently visible, with its own
   surface + border so the row reads as a card grid. isolation:isolate
   gives ::before a fresh stacking context so the stripe paints above
   the card surface but below the card content. */
.iteration-loop--row .iteration-detail__item {
  position: relative;
  inset: auto;
  opacity: 1;
  transform: none;
  animation: none;
  padding: var(--wp--preset--spacing--40);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--md);
  overflow: hidden;
  isolation: isolate;
}

/* Card H3 right-sized for narrow grid cells. The global h3 token
   (clamp 25–42px) overflows when the card is ~200px wide; this clamp
   keeps the title 18–24px so "Rozmowa" / "Feedback" fit on a single
   line at desktop and wrap cleanly on mobile. text-wrap: balance
   evens out 2-line wraps when copy grows. */
.iteration-loop--row .iteration-detail__name {
  font-size: clamp(1.125rem, 1.6vw, 1.5rem);
  line-height: 1.2;
  text-wrap: balance;
}

/* Description: nudge down a touch from the global 1rem so 5 cards
   abreast stay readable without feeling cramped. Existing 1.55
   line-height is preserved by the parent rule. */
.iteration-loop--row .iteration-detail__desc {
  font-size: 0.9375rem;
}

/* Traveling "now active" stripe — same negative-delay schedule as the
   ring arc + node pulses, so the eye sees a single coordinated 14s
   beat across the whole section. transform: scaleX is GPU-composited
   (no layout cost), opacity is the second axis so the stripe fades in
   AND draws at the same time. */
.iteration-loop--row .iteration-detail__item::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: var(--brand);
  transform-origin: left center;
  transform: scaleX(0);
  opacity: 0;
  animation: iteration-stripe-show 14s infinite;
  z-index: 1;
}
.iteration-loop--row .iteration-detail__item--1::before { animation-delay: 0s;     }
.iteration-loop--row .iteration-detail__item--2::before { animation-delay: -11.2s; }
.iteration-loop--row .iteration-detail__item--3::before { animation-delay: -8.4s;  }
.iteration-loop--row .iteration-detail__item--4::before { animation-delay: -5.6s;  }
.iteration-loop--row .iteration-detail__item--5::before { animation-delay: -2.8s;  }

@keyframes iteration-stripe-show {
  0%   { opacity: 0; transform: scaleX(0); }
  3%   { opacity: 1; transform: scaleX(1); }
  18%  { opacity: 1; transform: scaleX(1); }
  22%  { opacity: 0; transform: scaleX(1); }
  100% { opacity: 0; transform: scaleX(0); }
}

/* @property registers --p as an animatable <angle>; the browser
   interpolates between 0deg and 360deg (instead of step-snapping like
   un-typed custom-props). Required for conic-gradient to sweep
   smoothly. Chrome 85+, Firefox 128+, Safari 16.4+. Older Firefox
   ESR 115 falls back to a step animation — still readable. */
@property --p { syntax: "<angle>"; initial-value: 0deg; inherits: false; }

/* Ring container. --r drives radius, --thickness drives ring width,
   --cycle is the loop duration (set inline on the element so the
   @property + keyframes share a single source of truth). */
.iteration-ring {
  --r: clamp(110px, 22vw, 180px);
  --thickness: 10px;
  --cycle: 14s;
  --label-offset: clamp(48px, 5vw, 64px);
  position: relative;
  width: calc(var(--r) * 2);
  height: calc(var(--r) * 2);
  flex: 0 0 auto;
  margin-inline: auto;
  /* Padding around the ring so outer labels don't get clipped */
  padding: var(--label-offset);
  box-sizing: content-box;
}

/* Sweeping arc — conic-gradient with --p as the cutoff angle. The
   trail is brand-soft (so the user sees "where we've been"), the
   leading edge fades to brand. Drop-shadow is brand-soft at low alpha
   for a subtle glow without paint-bombing the rest of the section. */
.iteration-ring__arc {
  position: absolute;
  inset: var(--label-offset);
  border-radius: 50%;
  background:
    conic-gradient(
      from -90deg,
      var(--brand) 0deg var(--p),
      var(--brand-soft) var(--p) 360deg
    );
  filter: drop-shadow(0 0 16px oklch(0.55 0.20 270 / 0.15));
  animation: iteration-arc-sweep var(--cycle) infinite linear;
}

@keyframes iteration-arc-sweep {
  to { --p: 360deg; }
}

/* Inner disc that masks the arc into a thick ring. Uses surface-3
   (the section's bleed surface) so the centre reads as continuous
   with the section background. Avoids Safari's `mask: radial-gradient`
   1px aliasing on retina by using a real stacked element instead. */
.iteration-ring__core {
  position: absolute;
  inset: calc(var(--label-offset) + var(--thickness));
  border-radius: 50%;
  background: var(--section-bg, var(--surface-3));
  box-shadow:
    inset 0 0 0 1px var(--border-strong),
    0 1px 0 0 var(--surface) inset;
}

/* Centre narrator — five phase labels stacked absolutely at the ring's
   geometric centre. Only one is visible at a time on the same 14s
   cycle as the arc + nodes + detail panel. Mono caps reads as a
   dashboard "current state" indicator. */
.iteration-ring__hub {
  position: absolute;
  inset: var(--label-offset);
  display: grid;
  place-items: center;
  pointer-events: none;
  text-align: center;
}
.iteration-ring__eyebrow {
  position: absolute;
  top: clamp(28%, 30%, 32%);
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.iteration-ring__phase {
  /* All five phases occupy the same centred slot inside the grid hub;
     CSS-only crossfade picks one at a time. grid-area:1/1 stacks them
     without absolute-positioning the parent grid. */
  grid-area: 1 / 1;
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: clamp(1rem, 2.4vw, 1.375rem);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
  opacity: 0;
  animation: iteration-phase-show var(--cycle) infinite;
}
.iteration-ring__phase--1 { animation-delay: 0s;     }
.iteration-ring__phase--2 { animation-delay: -11.2s; }
.iteration-ring__phase--3 { animation-delay: -8.4s;  }
.iteration-ring__phase--4 { animation-delay: -5.6s;  }
.iteration-ring__phase--5 { animation-delay: -2.8s;  }

@keyframes iteration-phase-show {
  0%, 18%   { opacity: 1; transform: translateY(0); }
  22%, 100% { opacity: 0; transform: translateY(-2px); }
}

/* Phase nodes — absolutely centred, then offset along the ring via
   custom-prop angle math. The double-rotate trick keeps the dot ON
   the ring while letting the label sit upright. --n is set inline
   per node (1..5), --phase-count on the ring container. */
.iteration-ring__node {
  --angle: calc(-90deg + (var(--n) - 1) * (360deg / var(--phase-count)));
  position: absolute;
  top: calc(var(--label-offset) + var(--r));
  left: calc(var(--label-offset) + var(--r));
  width: 0;
  height: 0;
  transform: rotate(var(--angle)) translateY(calc(var(--r) * -1));
}

.iteration-ring__dot {
  position: absolute;
  inset: 0;
  width: 18px;
  height: 18px;
  margin: -9px;
  border-radius: 50%;
  background: var(--surface-3);
  border: 2px solid var(--border-strong);
  transform: rotate(calc(var(--angle) * -1));
  animation: iteration-node-pulse var(--cycle) infinite;
}
.iteration-ring__node--1 .iteration-ring__dot { animation-delay: 0s;     }
.iteration-ring__node--2 .iteration-ring__dot { animation-delay: -11.2s; }
.iteration-ring__node--3 .iteration-ring__dot { animation-delay: -8.4s;  }
.iteration-ring__node--4 .iteration-ring__dot { animation-delay: -5.6s;  }
.iteration-ring__node--5 .iteration-ring__dot { animation-delay: -2.8s;  }

@keyframes iteration-node-pulse {
  0%, 18% {
    background: var(--brand);
    border-color: var(--brand-strong);
    transform: rotate(calc(var(--angle) * -1)) scale(1.25);
    box-shadow: 0 0 0 4px var(--brand-soft);
  }
  22%, 100% {
    background: var(--surface-3);
    border-color: var(--border-strong);
    transform: rotate(calc(var(--angle) * -1)) scale(1);
    box-shadow: 0 0 0 0 transparent;
  }
}

/* Outer label — sits beyond the dot along the same radial. The double
   rotate(-angle) keeps the text horizontal regardless of node position.
   Hidden on small viewports — the centre narrator + detail panel are
   already authoritative. */
.iteration-ring__label {
  position: absolute;
  top: calc(var(--label-offset) * -0.7);
  left: 50%;
  transform: translateX(-50%) rotate(calc(var(--angle) * -1));
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
  white-space: nowrap;
}

/* ---------- Synchronized detail panel ----------------------------------
   Right-column counterpart to the diagram. Five <li> items stacked
   absolutely, only one visible at a time on the same 14s cycle. Each
   item slides up subtly on enter for a polished feel. All five items
   are in the DOM at all times — search engines and screen readers see
   the full ordered list, sighted users see one at a time.
   --------------------------------------------------------------------- */
.iteration-detail {
  flex: 1 1 320px;
  list-style: none;
  padding: 0;
  margin: 0;
  position: relative;
  /* Min-height accommodates the tallest item (Build description is
     longest) so the panel doesn't collapse when an item changes. */
  min-height: clamp(13rem, 18vw, 16rem);
}
.iteration-detail__item {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--20);
  opacity: 0;
  transform: translateY(8px);
  animation: iteration-detail-show 14s infinite;
}
.iteration-detail__item--1 { animation-delay: 0s;     }
.iteration-detail__item--2 { animation-delay: -11.2s; }
.iteration-detail__item--3 { animation-delay: -8.4s;  }
.iteration-detail__item--4 { animation-delay: -5.6s;  }
.iteration-detail__item--5 { animation-delay: -2.8s;  }

@keyframes iteration-detail-show {
  0%   { opacity: 0; transform: translateY(8px); }
  3%   { opacity: 1; transform: translateY(0);   }
  18%  { opacity: 1; transform: translateY(0);   }
  22%  { opacity: 0; transform: translateY(-4px); }
  100% { opacity: 0; transform: translateY(8px); }
}

.iteration-detail__counter {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  font-weight: 600;
  color: var(--brand);
}
.iteration-detail__name {
  font-family: var(--wp--preset--font-family--plex-serif);
  font-size: clamp(1.75rem, 3.5vw, 2.5rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--ink);
  margin: 0;
}
.iteration-detail__desc {
  margin: 0;
  font-size: 1rem;
  line-height: 1.55;
  color: var(--ink-muted);
}
.iteration-detail__chip {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  padding: 0.25rem 0.75rem;
  background: var(--brand-soft);
  color: var(--brand-strong);
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  border-radius: var(--wp--custom--radius--pill);
  margin-top: auto;
}

/* Mobile: outer ring labels overlap the centre narrator at small radii.
   Hide them — the detail panel below already carries the full phase
   context. The ring stays visually balanced as a clean five-dot
   constellation. Row variant additionally tightens the ring so it
   doesn't dominate when cards stack vertically. */
@media (max-width: 600px) {
  .iteration-ring { --label-offset: 16px; }
  .iteration-ring__label { display: none; }
  .iteration-loop--row .iteration-ring { --r: clamp(72px, 22vw, 96px); --thickness: 6px; }
}

@media (prefers-reduced-motion: reduce) {
  /* Ring: freeze the arc at full ring (suggesting "all phases lit"),
     kill the node pulse + centre narrator cycling. The phase data is
     still conveyed by the static detail-panel list below. */
  .iteration-ring__arc {
    animation: none;
    background: conic-gradient(var(--brand-soft), var(--brand-soft));
    filter: none;
  }
  .iteration-ring__dot {
    animation: none;
    background: var(--brand-soft);
    border-color: var(--brand);
    /* Strip the keyframe transform so the rotate-cancel still applies */
    transform: rotate(calc(var(--angle) * -1));
    box-shadow: none;
  }
  /* Park on the first phase as a static "current state" indicator —
     the detail-panel list below carries the full phase context.
     (No-op for the row variant: the centre narrator is removed.) */
  .iteration-ring__phase { animation: none; opacity: 0; }
  .iteration-ring__phase--1 { opacity: 1; }

  /* Row variant: stripe stops travelling — no card highlighted, all
     five cards equal weight. Static visual emphasis is carried by
     each card's surface + border. */
  .iteration-loop--row .iteration-detail__item::before {
    animation: none;
    opacity: 0;
    transform: scaleX(0);
  }

  /* Split variant (legacy): stack all five items vertically as a
     static labeled list with hairline separators. The cycling
     becomes a simple read-through at user's pace. */
  .iteration-detail { min-height: 0; }
  .iteration-detail__item {
    position: relative;
    inset: auto;
    opacity: 1;
    transform: none;
    animation: none;
    padding-block: var(--wp--preset--spacing--30);
    border-bottom: 1px solid var(--border);
  }
  .iteration-detail__item:last-child { border-bottom: 0; }
  /* Row variant cards have their own border + radius — the legacy
     "border-bottom separator" rule above must not apply here. */
  .iteration-loop--row .iteration-detail__item { border-bottom: 1px solid var(--border); }
}

/* Display emphasis — italic-serif word inside H1 (e.g. "MVP") */
.display-em {
  font-family: var(--wp--preset--font-family--plex-serif);
  font-style: italic;
  font-weight: 400;
  color: var(--brand);
  letter-spacing: -0.01em;
}

/* Status pills — small chip with a leading dot for hero + contact bookend */
.hero-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: var(--wp--preset--spacing--30);
}
.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.25rem 0.625rem;
  border-radius: var(--wp--custom--radius--pill);
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--ink-muted);
}
.pill--success {
  color: var(--success);
  background: color-mix(in oklch, var(--success) 10%, var(--surface));
  border-color: color-mix(in oklch, var(--success) 30%, transparent);
}
.pill--neutral {
  color: var(--ink-muted);
  background: var(--surface-2);
  border-color: var(--border);
}

/* ----------------------------------------------------------------------
   Project cards — featured-image + post-title + excerpt with sharper
   hover. :has() lets the whole card lift when the title link is
   hovered, so the entire card feels clickable even though only the
   title and image are wrapped in <a>. Falls back to image-only hover
   in browsers without :has() (Firefox <121, ~3% by 2026).
   ---------------------------------------------------------------------- */
.project-card .wp-block-post-featured-image,
.wp-block-post-template .wp-block-post-featured-image {
  position: relative;
  overflow: hidden;
  border-radius: var(--wp--custom--radius--md);
}
.project-card .wp-block-post-featured-image::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(120deg, transparent 0%, var(--brand-soft) 50%, transparent 100%);
  opacity: 0;
  transition: opacity 300ms ease;
  mix-blend-mode: overlay;
  pointer-events: none;
}
.project-card:has(a:hover) .wp-block-post-featured-image::after {
  opacity: 0.4;
}
.project-card .wp-block-post-featured-image img,
.wp-block-post-template .wp-block-post-featured-image img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 400ms cubic-bezier(0.4, 0, 0.2, 1);
}
.project-card:hover .wp-block-post-featured-image img,
.wp-block-post-template .project-card:hover .wp-block-post-featured-image img {
  transform: scale(1.02);
}

/* Image hover via :has — when any link inside the card is hovered,
   the whole card lifts. */
.project-card:has(a:hover) {
  border-color: var(--brand);
  transform: translateY(-2px);
  background: var(--surface-3);
}

/* Project title — keep brand color on hover but lose the underline so
   the headline reads cleanly. */
.project-card .wp-block-post-title a {
  color: var(--ink);
  text-decoration: none;
  transition: color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.project-card .wp-block-post-title a:hover {
  color: var(--brand);
  text-decoration: none;
}

/* Placeholder SVG (rendered by portfolio-core when a project has no
   featured image). The plugin's filter wraps it in a
   .wp-block-post-featured-image figure so it inherits hover scale and
   border-radius from the rules above. */
.project-placeholder {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  background: var(--surface-3);
}

/* ----------------------------------------------------------------------
   Stats — mega-size serif numbers with colored-dot label rotation and
   mono citation lines. Each tile uses a CSS custom prop --dot for the
   per-tile accent, set inline on the column to rotate brand → accent →
   success → warning across the 4 tiles.
   ---------------------------------------------------------------------- */
.stat-tile { display: block; }
.stat-tile__num {
  font-family: var(--wp--preset--font-family--plex-serif);
  font-size: clamp(2.75rem, 5vw, 4.5rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  margin: 0 0 var(--wp--preset--spacing--20);
  color: var(--ink);
  white-space: nowrap;
}
.stat-tile__plus {
  font-size: 0.5em;
  font-weight: 600;
  color: var(--brand);
  margin-left: 0.15em;
  vertical-align: 0.4em;
}
.stat-tile__label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9375rem;
  color: var(--ink-muted);
  margin: 0 0 0.25rem;
  line-height: 1.4;
}
.stat-tile__dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--dot, var(--brand));
  flex-shrink: 0;
}
.stat-tile__cite {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.75rem;
  color: var(--ink-faint);
  margin: 0;
  line-height: 1.5;
}

/* ----------------------------------------------------------------------
   Process — 4-step horizontal flow on wide screens, vertical stack on
   mobile. Each step has a left border that becomes brand-coloured on
   hover, mono-style numeral, serif title, sans description. Linear-
   adjacent: structured, restrained, no flashy connectors.
   ---------------------------------------------------------------------- */
.process-steps {
  list-style: none;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--wp--preset--spacing--40);
  padding: 0;
  margin: var(--wp--preset--spacing--50) 0 0;
  counter-reset: process;
}
@media (min-width: 860px) {
  .process-steps {
    grid-template-columns: repeat(4, 1fr);
    gap: var(--wp--preset--spacing--50);
  }
}
.process-step {
  position: relative;
  padding: var(--wp--preset--spacing--40);
  border: 1px solid transparent;
  border-top-width: 3px;
  border-radius: var(--wp--custom--radius--md);
  background-image:
    linear-gradient(var(--surface-2), var(--surface-2)),
    var(--gradient-brand-accent);
  background-origin: border-box;
  background-clip: padding-box, border-box;
  transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow  200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.process-step:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-card-lifted);
}
.process-step__num {
  display: inline-block;
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--brand);
  background: var(--brand-soft);
  padding: 0.125rem 0.375rem;
  border-radius: var(--wp--custom--radius--sm);
  margin-bottom: var(--wp--preset--spacing--30);
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
}
.process-step__title {
  font-family: var(--wp--preset--font-family--plex-serif);
  font-size: 1.25rem;
  font-weight: 600;
  margin: 0 0 0.5rem;
  color: var(--ink);
}
.process-step__desc {
  color: var(--ink-muted);
  font-size: 0.9375rem;
  line-height: 1.5;
  margin: 0;
}

/* ----------------------------------------------------------------------
   Motion polish — entrance fade.
   - @starting-style runs once on first paint to fade-in-up the major
     sections (alignwide direct children of <main>). Chrome/Edge 117+,
     Safari 17.4+, Firefox 129+. Wrapped in @supports so unsupported
     browsers skip cleanly.
   - Per-card scroll-driven reveal was removed in Tier 3.15 — see the
     deletion note below for the rationale.
   prefers-reduced-motion override at the bottom kills everything.
   ---------------------------------------------------------------------- */
@supports (transition-behavior: allow-discrete) {
  .wp-site-blocks > main > .alignwide {
    transition:
      opacity 600ms cubic-bezier(0.4, 0, 0.2, 1),
      transform 600ms cubic-bezier(0.4, 0, 0.2, 1);
    transition-behavior: allow-discrete;
  }
  @starting-style {
    .wp-site-blocks > main > .alignwide {
      opacity: 0;
      transform: translateY(12px);
    }
  }
}

/* Scroll-driven entrance animation removed in Tier 3.15 — the
   `entry 0% cover 30%` range left elements at opacity:0 on first paint
   in Chrome/Safari before scroll. The `@starting-style` first-paint
   fade-in above is preserved as the canonical entrance motion. */

/* ======================================================================
   Cennik — pricing page. Reference-doc voice (calmer than the sales
   pages) with a 2-col section-head pattern (lockup left, animated
   meta-strip right) and tier-card grids for MVP + WordPress.
   ====================================================================== */

/* ---- Section frame ---------------------------------------------------- */
.cennik-hero.alignwide,
.cennik-rates.alignwide,
.cennik-tiers.alignwide,
.cennik-app.alignwide,
.cennik-addons.alignwide,
.cennik-wp.alignwide,
.cennik-exclusions.alignwide,
.cennik-deliverables.alignwide,
.cennik-consulting.alignwide,
.cennik-faq.alignwide {
  max-width: min(1360px, calc(100% - 2rem));
}

.cennik-hero,
.cennik-rates,
.cennik-tiers,
.cennik-app,
.cennik-addons,
.cennik-wp,
.cennik-exclusions,
.cennik-deliverables,
.cennik-consulting,
.cennik-faq {
  padding-top: clamp(2.5rem, 5vw, 4.5rem) !important;
  padding-bottom: clamp(2.5rem, 5vw, 4.5rem) !important;
}

/* WP's constrained-layout caps direct-child blocks at contentSize (720px)
   with margin: auto. Override across the cennik to keep one flush-left
   baseline. */
.cennik-hero > *,
.cennik-rates > *,
.cennik-tiers > *,
.cennik-app > *,
.cennik-addons > *,
.cennik-wp > *,
.cennik-exclusions > *,
.cennik-deliverables > *,
.cennik-consulting > *,
.cennik-faq > * {
  max-width: none !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
}

/* ---- Section head (flush-left lockup; meta-strip removed per design
   review — duplicated the price info already in the cards below) ------ */
.cennik-section-head {
  margin-bottom: var(--wp--preset--spacing--40);
}
.cennik-section-head__lockup {
  display: flex;
  flex-direction: column;
  gap: 0.875rem;
  max-width: 50rem;
}
.cennik-section-head--hero .cennik-section-head__lockup {
  gap: 1.25rem;
  max-width: 38rem;
}
.cennik-section-head__lockup > * { margin: 0 !important; }
.cennik-section-head__lockup .section-num { margin-bottom: 0 !important; }

/* H1 hero — display serif, balanced wrap. !important needed to defeat
   WP's .has-display-font-size which ships with its own !important. */
.cennik-hero h1.has-display-font-size,
.cennik-hero h1 {
  font-size: clamp(2rem, 4vw, 3.25rem) !important;
  font-weight: 600 !important;
  line-height: 1.08 !important;
  letter-spacing: -0.02em !important;
  text-wrap: balance;
}

/* Section H2 — Plex Sans 600 for the pricing-sheet feel. Same !important
   reason: WP's heading block typography ships with !important. */
.cennik-rates h2,
.cennik-tiers h2,
.cennik-app h2,
.cennik-addons h2,
.cennik-wp h2,
.cennik-exclusions h2,
.cennik-deliverables h2,
.cennik-consulting h2,
.cennik-faq h2 {
  font-family: var(--wp--preset--font-family--plex-sans) !important;
  font-size: clamp(1.5rem, 2.5vw, 2rem) !important;
  font-weight: 600 !important;
  line-height: 1.2 !important;
  letter-spacing: -0.015em !important;
  text-wrap: balance;
}

/* Section intro paragraphs */
.cennik-hero__lead,
.cennik-tiers__lead,
.cennik-app__lead,
.cennik-addons__lead,
.cennik-wp__lead,
.cennik-consulting__lead {
  font-size: 1rem;
  line-height: 1.6;
  color: var(--ink-muted);
}
.cennik-hero__lead { font-size: 1.0625rem; }

/* ---- Meta-strip ------------------------------------------------------ */
.cennik-meta-strip {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  padding: 1.125rem 1.25rem;
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--md, 12px);
  background: var(--surface);
  box-shadow: 0 8px 24px -16px oklch(0 0 0 / 0.12);
  animation: cennik-meta-strip-in 700ms cubic-bezier(0.22, 1, 0.36, 1) backwards;
  animation-delay: 80ms;
}
@starting-style {
  .cennik-meta-strip {
    opacity: 0;
    transform: translateY(12px) scale(0.98);
  }
}
@keyframes cennik-meta-strip-in {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@supports (animation-timeline: view()) {
  .cennik-meta-strip {
    animation: cennik-meta-strip-in linear both;
    animation-timeline: view();
    animation-range: entry 10% cover 30%;
  }
}
.cennik-meta-strip__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.8125rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px dashed var(--border);
}
.cennik-meta-strip__row:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}
.cennik-meta-strip__k {
  color: var(--ink-muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 0.6875rem;
}
.cennik-meta-strip__v {
  color: var(--ink);
  font-weight: 600;
  text-align: right;
}

/* Hero pills */
.cennik-hero__pills {
  list-style: none;
  margin: 0 !important;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.cennik-hero__pills li::before { content: none; }
.cennik-hero__pills li { padding-left: 0; }
.cennik-hero__pills a { color: inherit; text-decoration: none; }
.cennik-hero__pills .is-style-pill {
  transition: background-color 200ms ease, transform 200ms ease;
}
.cennik-hero__pills .is-style-pill:hover {
  background: var(--brand-soft);
  transform: translateY(-1px);
}

/* ---- Section 01 · Rate cards ----------------------------------------- */
.cennik-rates__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--wp--preset--spacing--40);
}
.cennik-rates__card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--lg, 16px);
  padding: 2.25rem 2rem 1.75rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  transition: border-color 200ms ease, transform 200ms ease, box-shadow 200ms ease;
}
.cennik-rates__card:hover {
  border-color: var(--border-strong);
  transform: translateY(-2px);
  box-shadow: 0 16px 40px -24px oklch(0 0 0 / 0.18);
}
.cennik-rates__card:nth-child(1) {
  background: linear-gradient(160deg, var(--brand-soft), var(--surface) 80%);
  border-color: color-mix(in srgb, var(--brand) 35%, transparent);
}
.cennik-rates__card:nth-child(1)::before {
  content: 'Polecane';
  position: absolute;
  top: 1rem;
  right: 1rem;
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand);
  background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--brand) 35%, transparent);
  border-radius: 999px;
  padding: 0.25rem 0.625rem;
}
.cennik-rates__price {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}
.cennik-rates__prefix {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-weight: 500;
  font-size: 0.9375rem;
  letter-spacing: 0.04em;
  text-transform: lowercase;
  color: var(--ink-muted);
  opacity: 0.7;
}
.cennik-rates__amount {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: clamp(2.5rem, 4.5vw, 3.5rem);
  font-weight: 600;
  color: var(--ink);
  line-height: 1;
  letter-spacing: -0.02em;
}
.cennik-rates__unit {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.9375rem;
  color: var(--ink-muted);
}
.cennik-rates__name {
  font-size: 1.25rem;
  font-weight: 600;
  margin: 0;
}
.cennik-rates__desc { color: var(--ink-muted); line-height: 1.55; margin: 0; }
.cennik-rates__bullets {
  list-style: none;
  padding: 0;
  margin: 0.25rem 0 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.cennik-rates__bullets li::before { content: none; }
.cennik-rates__bullets li {
  position: relative;
  padding-left: 1.5rem;
  color: var(--ink-muted);
  font-size: 0.9375rem;
  line-height: 1.45;
}
.cennik-rates__bullets li::after {
  content: '✓';
  position: absolute;
  left: 0;
  top: 0;
  color: var(--brand);
  font-weight: 700;
}
.cennik-rates__tag {
  margin-top: auto;
  font-size: 0.8125rem;
  color: var(--ink-faint);
  padding-top: 0.75rem;
  border-top: 1px dashed var(--border);
}

/* ---- Section 02 + 05 · Tier cards (MVP + WordPress) ------------------ */
.cennik-tiers__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.25rem;
}
.cennik-tiers__grid--wp {
  /* 5 tiers — auto-fit so they reflow into 2-3 cols depending on viewport */
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
}
@media (max-width: 1099px) {
  .cennik-tiers__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.cennik-tier {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1.75rem 1.5rem 1.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--lg, 16px);
  transition: border-color 200ms ease, transform 200ms ease, box-shadow 200ms ease;
}
.cennik-tier:hover {
  border-color: color-mix(in srgb, var(--brand) 35%, transparent);
  transform: translateY(-3px);
  box-shadow: 0 16px 36px -20px oklch(0.55 0.20 270 / 0.22);
}
.cennik-tier--featured {
  background: linear-gradient(160deg, var(--brand-soft), var(--surface) 75%);
  border-color: color-mix(in srgb, var(--brand) 40%, transparent);
  box-shadow: 0 12px 32px -20px oklch(0.55 0.20 270 / 0.25);
}
.cennik-tier--featured:hover {
  box-shadow: 0 24px 48px -20px oklch(0.55 0.20 270 / 0.35);
}
.cennik-tier__badge {
  position: absolute;
  top: 0.875rem;
  right: 0.875rem;
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand);
  background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--brand) 35%, transparent);
  border-radius: 999px;
  padding: 0.25rem 0.625rem;
  font-weight: 600;
}

.cennik-tier__head { display: flex; flex-direction: column; gap: 0.375rem; }
.cennik-tier__name {
  font-size: 1.125rem;
  font-weight: 600;
  margin: 0;
  color: var(--ink);
}
.cennik-tier__price {
  display: flex;
  align-items: baseline;
  gap: 0.375rem;
  margin-top: 0.25rem;
}
.cennik-tier__prefix {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.8125rem;
  text-transform: lowercase;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  opacity: 0.75;
}
.cennik-tier__amount {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: clamp(1.5rem, 2.5vw, 1.875rem);
  font-weight: 600;
  color: var(--ink);
  line-height: 1;
  letter-spacing: -0.02em;
}
.cennik-tier__asterisk {
  font-family: var(--wp--preset--font-family--plex-mono);
  color: var(--brand);
  font-weight: 600;
  font-size: 0.875rem;
  margin-left: 0.125rem;
  align-self: flex-start;
  line-height: 1;
  margin-top: 0.125rem;
}
.cennik-tier__duration {
  font-size: 0.8125rem;
  color: var(--ink-muted);
  margin: 0;
}
.cennik-tier__desc {
  font-size: 0.9375rem;
  color: var(--ink-muted);
  line-height: 1.5;
  margin: 0;
}
.cennik-tier__bullets {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.cennik-tier__bullets li::before { content: none; }
.cennik-tier__bullets li {
  position: relative;
  padding-left: 1.375rem;
  font-size: 0.875rem;
  color: var(--ink-muted);
  line-height: 1.45;
}
.cennik-tier__bullets li::after {
  content: '✓';
  position: absolute;
  left: 0;
  top: 0;
  color: var(--brand);
  font-weight: 700;
  font-size: 0.875rem;
}

.cennik-tier__cta {
  margin-top: auto;
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.625rem 1.125rem;
  background: var(--ink);
  color: var(--surface);
  border-radius: 999px;
  font-family: var(--wp--preset--font-family--plex-sans);
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  border: 1px solid var(--ink);
  transition: background-color 200ms ease, transform 200ms ease, box-shadow 200ms ease;
}
.cennik-tier__cta:hover {
  background: var(--brand);
  border-color: var(--brand);
  transform: translateY(-1px);
  box-shadow: 0 8px 20px -10px oklch(0.55 0.20 270 / 0.4);
}
.cennik-tier__cta--featured {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--surface);
}
.cennik-tier__cta--featured:hover {
  background: var(--ink);
  border-color: var(--ink);
}

/* Complexity note — the "*" caveat below tier grids */
.cennik-complexity-note {
  margin: 1.5rem 0 0 !important;
  padding: 1rem 1.25rem;
  background: var(--surface);
  border: 1px dashed var(--border);
  border-radius: var(--wp--custom--radius--md, 12px);
  font-size: 0.875rem;
  color: var(--ink-muted);
  line-height: 1.55;
  font-family: var(--wp--preset--font-family--plex-sans);
}

/* Subtle asterisk marker on individual prices */
.cennik-app__asterisk {
  font-family: var(--wp--preset--font-family--plex-mono);
  color: var(--brand);
  font-weight: 700;
  margin-left: 0.125rem;
  font-size: 0.9375rem;
  vertical-align: super;
  line-height: 1;
}

/* ---- Section 03 · MVP component grid -------------------------------- */
.cennik-app__components {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}
@media (max-width: 1099px) {
  .cennik-app__components { grid-template-columns: repeat(2, 1fr); }
}
.cennik-app__components--addons {
  /* same grid as MVP but for add-ons */
}
.cennik-app__card {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto 1fr auto;
  column-gap: 0.875rem;
  row-gap: 0.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--md, 12px);
  padding: 1.25rem 1.25rem 1.125rem;
  transition: border-color 200ms ease, transform 200ms ease, box-shadow 200ms ease;
}
.cennik-app__card:hover {
  border-color: color-mix(in srgb, var(--brand) 35%, transparent);
  transform: translateY(-2px);
  box-shadow: 0 12px 28px -16px oklch(0.55 0.20 270 / 0.25);
}
.cennik-app__icon {
  grid-column: 1;
  grid-row: 1 / span 2;
  align-self: start;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 8px;
  background: var(--brand-soft);
  font-size: 1.125rem;
  line-height: 1;
  font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', system-ui, sans-serif;
  flex-shrink: 0;
}
.cennik-app__body { display: contents; }
.cennik-app__name {
  grid-column: 2;
  grid-row: 1;
  font-size: 1.0625rem;
  font-weight: 600;
  margin: 0;
  line-height: 1.3;
  color: var(--ink);
}
.cennik-app__desc {
  grid-column: 2;
  grid-row: 2;
  align-self: start;
  font-size: 0.875rem;
  color: var(--ink-muted);
  margin: 0;
  line-height: 1.5;
}
.cennik-app__price {
  grid-column: 1 / -1;
  grid-row: 3;
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px dashed var(--border);
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--brand);
  white-space: nowrap;
  text-align: right;
}
.cennik-app__price-prefix {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-weight: 500;
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-transform: lowercase;
  color: var(--ink-faint);
  opacity: 0.85;
}

/* Total band */
.cennik-app__total {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 1.5rem 2rem;
  background: linear-gradient(135deg, var(--ink), color-mix(in srgb, var(--ink) 80%, var(--brand)));
  color: var(--surface);
  border-radius: var(--wp--custom--radius--lg, 16px);
  padding: 1.75rem 2rem;
  margin-top: 1.5rem !important;
  box-shadow: 0 24px 60px -28px oklch(0.55 0.20 270 / 0.4);
}
.cennik-app__total-side { display: flex; flex-direction: column; gap: 0.25rem; }
.cennik-app__total-label { font-size: 1rem; font-weight: 600; letter-spacing: 0.01em; }
.cennik-app__total-sub { font-size: 0.875rem; opacity: 0.7; }
.cennik-app__total-value {
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  font-weight: 700;
  color: var(--surface);
  letter-spacing: -0.02em;
  white-space: nowrap;
}
.cennik-app__total-prefix {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-weight: 500;
  font-size: 0.875rem;
  letter-spacing: 0.04em;
  text-transform: lowercase;
  opacity: 0.65;
  margin-right: 0.125rem;
}

/* ---- Section 06 · Exclusions (card grid for consistency) ------------ */
.cennik-exclusions__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}
@media (max-width: 1099px) {
  .cennik-exclusions__grid { grid-template-columns: repeat(2, 1fr); }
}
.cennik-exclusions__card {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  padding: 1.25rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--md, 12px);
  transition: border-color 200ms ease, transform 200ms ease;
}
.cennik-exclusions__card:hover {
  border-color: color-mix(in srgb, var(--brand) 35%, transparent);
  transform: translateY(-2px);
}
.cennik-exclusions__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 8px;
  background: var(--brand-soft);
  font-size: 1.125rem;
  line-height: 1;
  font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', system-ui, sans-serif;
}
.cennik-exclusions__title {
  font-size: 1rem;
  font-weight: 600;
  margin: 0;
  color: var(--ink);
}
.cennik-exclusions__desc {
  margin: 0;
  font-size: 0.9375rem;
  color: var(--ink-muted);
  line-height: 1.55;
}

/* ---- Section 07 · Deliverables -------------------------------------- */
.cennik-deliverables__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--wp--preset--spacing--30);
}
@media (max-width: 1099px) {
  .cennik-deliverables__grid { grid-template-columns: repeat(2, 1fr); }
}
.cennik-deliverables__card {
  position: relative;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--md, 12px);
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  transition: border-color 200ms ease, transform 200ms ease, box-shadow 200ms ease;
}
.cennik-deliverables__card:hover {
  border-color: color-mix(in srgb, var(--brand) 35%, transparent);
  transform: translateY(-2px);
  box-shadow: 0 12px 28px -16px oklch(0.55 0.20 270 / 0.2);
}
.cennik-deliverables__card .card-deco {
  position: absolute;
  top: -10px;
  right: -10px;
  pointer-events: none;
  opacity: 0.85;
  transition: opacity 200ms ease, transform 200ms ease;
}
.cennik-deliverables__card:hover .card-deco {
  opacity: 1;
  transform: scale(1.08);
}
.cennik-deliverables__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 8px;
  background: var(--brand-soft);
  font-size: 1.25rem;
  line-height: 1;
  font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', system-ui, sans-serif;
  margin-bottom: 0.25rem;
}
.cennik-deliverables__title { font-size: 1rem; font-weight: 600; margin: 0; color: var(--ink); }
.cennik-deliverables__desc { margin: 0; font-size: 0.9375rem; color: var(--ink-muted); line-height: 1.55; }

/* ---- Section 08 · Consulting menu ----------------------------------- */
.cennik-consulting__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--lg, 16px);
  background: var(--surface);
  overflow: hidden;
}
.cennik-consulting__item {
  padding: 1.25rem 1.5rem;
  border-bottom: 1px solid var(--border);
  transition: background-color 200ms ease;
}
.cennik-consulting__item::before { content: none; }
.cennik-consulting__item:hover { background: var(--surface-2); }
.cennik-consulting__item:last-child { border-bottom: 0; }
.cennik-consulting__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.cennik-consulting__name { font-size: 1.0625rem; font-weight: 600; margin: 0; color: var(--ink); }
.cennik-consulting__price {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--brand);
  white-space: nowrap;
  padding: 0.3125rem 0.75rem;
  border: 1px solid color-mix(in srgb, var(--brand) 30%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--brand-soft) 50%, transparent);
}
.cennik-consulting__price-prefix {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: lowercase;
  color: var(--brand);
  opacity: 0.65;
  margin-right: 0.125rem;
}
.cennik-consulting__desc {
  margin: 0.5rem 0 0;
  font-size: 0.9375rem;
  color: var(--ink-muted);
  line-height: 1.55;
}

/* ---- Section 09 · FAQ ----------------------------------------------- */
.cennik-faq__list {
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--lg, 16px);
  background: var(--surface);
  overflow: hidden;
}
.cennik-faq__item {
  border-bottom: 1px solid var(--border);
}
.cennik-faq__item:last-child { border-bottom: 0; }
.cennik-faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.125rem 1.5rem;
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  list-style: none;
  transition: color 200ms ease, background-color 200ms ease;
}
.cennik-faq__q::-webkit-details-marker { display: none; }
.cennik-faq__q::after {
  content: '';
  width: 0.625rem;
  height: 0.625rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-0.0625rem, -0.0625rem);
  transition: transform 200ms ease;
  flex-shrink: 0;
  opacity: 0.55;
}
.cennik-faq__item[open] .cennik-faq__q::after {
  transform: rotate(225deg) translate(-0.0625rem, -0.0625rem);
  opacity: 1;
}
.cennik-faq__q:hover { background: var(--surface-2); color: var(--brand); }
.cennik-faq__item[open] .cennik-faq__q { color: var(--brand); }
.cennik-faq__a {
  margin: 0;
  padding: 0 1.5rem 1.25rem;
  color: var(--ink-muted);
  line-height: 1.65;
  font-size: 1rem;
  max-width: 70ch;
}

/* ---- Responsive collapses ------------------------------------------- */
@media (max-width: 900px) {
  .cennik-section-head {
    grid-template-columns: 1fr;
    align-items: start;
  }
  .cennik-section-head__lockup { max-width: none; }
  .cennik-section-head--hero { align-items: start; }
}
@media (max-width: 768px) {
  .cennik-rates__grid,
  .cennik-app__components,
  .cennik-exclusions__grid,
  .cennik-deliverables__grid {
    grid-template-columns: 1fr;
  }
  .cennik-tiers__grid { grid-template-columns: 1fr; }
  .cennik-rates__card { padding: 1.75rem 1.5rem 1.5rem; }
  .cennik-rates__card:nth-child(1)::before { top: 0.75rem; right: 0.75rem; }
  .cennik-tier { padding: 1.5rem 1.25rem 1.25rem; }
  .cennik-tier__badge { top: 0.75rem; right: 0.75rem; }
  .cennik-app__total {
    grid-template-columns: 1fr;
    padding: 1.5rem;
  }
  .cennik-app__total-value { font-size: clamp(1.5rem, 8vw, 2rem); }
  .cennik-faq__q { padding: 1rem 1.25rem; font-size: 1rem; }
  .cennik-faq__a { padding: 0 1.25rem 1rem; }
  .cennik-consulting__item { padding: 1rem 1.25rem; }
}

/* Link-underline-grow on hover. Excludes anything that already has its
   own hover treatment (buttons, pills, kbd-hints, quote-card internals,
   stat tiles, section-num pills, project title link, trust-strip logos,
   site-nav links which use a color-only hover) so the underline doesn't
   pile on existing affordances. */
a:not(
  .wp-block-button__link,
  .kbd-hint,
  .pill,
  .pill *,
  .quote-card *,
  .stat-tile *,
  .section-num *,
  .project-card .wp-block-post-title a,
  .project-placeholder a,
  .trust-strip__logos *,
  .site-nav__links a,
  .services-panel a
):where(:hover, :focus-visible) {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.25em;
  text-decoration-color: var(--brand);
}

/* Project-card stack term renders as a brand-soft mono chip. */
.project-card .wp-block-post-terms {
  display: inline-block;
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand);
  background: var(--brand-soft);
  padding: 0.125rem 0.5rem;
  border-radius: var(--wp--custom--radius--sm);
  margin: 0 0 var(--wp--preset--spacing--20);
  align-self: flex-start;
}
.project-card .wp-block-post-terms a {
  color: inherit;
  text-decoration: none;
}

.pill:focus-visible {
  box-shadow: var(--ring-focus-strong);
  outline: none;
}

@media (prefers-reduced-motion: reduce) {
  .wp-site-blocks > main > .alignwide,
  .is-style-card,
  .stats-grid > .wp-block-column,
  .process-step,
  .tile,
  .tile:hover,
  .quote-card {
    animation: none !important;
    transition: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
  .is-style-card:hover,
  .tile:hover,
  .tile:hover .tile__arrow,
  .quote-card:hover,
  .project-card:hover,
  .process-step:hover {
    transform: none !important;
    box-shadow: none !important;
  }
}

.wp-block-heading,
.project-card .wp-block-post-title,
.project-card h2,
.project-card h3,
.is-style-card h2,
.is-style-card h3,
.services-section h3 {
  word-break: normal;
  overflow-wrap: anywhere;
  hyphens: auto;
}

/* Hamburger toggle — hidden by default, shown only at the mobile
   breakpoint. Plain <button>, JS-driven; replaces the prior <details>
   approach because closed-<details> children are removed from layout
   in modern Chromium and `display: inline-flex` cannot override that. */
.site-nav__toggle {
  display: none;
  background: transparent;
  border: 0;
  padding: 0.5rem;
  color: var(--ink);
  cursor: pointer;
}
.site-nav__toggle:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.site-nav__toggle-icon {
  display: inline-block;
  width: 1.5rem;
  height: 2px;
  background: currentColor;
  position: relative;
}
.site-nav__toggle-icon::before,
.site-nav__toggle-icon::after {
  content: '';
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  background: currentColor;
}
.site-nav__toggle-icon::before { top: -6px; }
.site-nav__toggle-icon::after  { top:  6px; }

@media (max-width: 768px) {
  .site-nav__toggle {
    display: inline-flex;
    align-items: center;
  }
  /* On mobile the dropdown panel must anchor to the viewport edges,
     not to the 40px-wide hamburger button. Drop the relative on
     .site-nav and let the absolute panel resolve against the sticky
     <header> (sticky establishes a containing block). */
  .site-nav {
    position: static;
  }
  .site-nav:not(.is-open) .site-nav__links {
    display: none;
  }
  .site-nav.is-open .site-nav__links {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    position: absolute;
    top: 100%;
    left: var(--wp--preset--spacing--20);
    right: var(--wp--preset--spacing--20);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--wp--custom--radius--md, 8px);
    padding: var(--wp--preset--spacing--20);
    box-shadow: 0 8px 24px rgb(0 0 0 / 0.08);
    z-index: 110;
  }
  .site-nav.is-open .site-nav__links a {
    padding: 0.75rem 0.5rem;
    border-bottom: 1px solid var(--border);
  }
  .site-nav.is-open .site-nav__links a:last-child { border-bottom: 0; }
  /* In the mobile dropdown the rows already have their own separators,
     and the pill treatment doesn't fit a vertical list. Flatten the CTA. */
  .site-nav.is-open .site-nav__links a.site-nav__cta {
    background: transparent;
    color: var(--ink);
    padding: 0.75rem 0.5rem;
    border-radius: 0;
    font-weight: 500;
  }
  .site-nav.is-open .site-nav__links a.site-nav__cta:hover,
  .site-nav.is-open .site-nav__links a.site-nav__cta:focus-visible,
  .site-nav.is-open .site-nav__links a.site-nav__cta[aria-current="page"] {
    background: transparent;
    color: var(--brand);
  }
  .site-nav.is-open .site-nav__links a[aria-current="page"] {
    color: var(--brand);
    font-weight: 600;
  }

  /* Usługi trigger inside the mobile drawer — flatten to row, let
     chevron read as accordion indicator. */
  .site-nav.is-open .site-nav__services-wrap {
    display: block;
    border-bottom: 1px solid var(--border);
  }
  .site-nav.is-open .site-nav__services-trigger {
    width: 100%;
    padding: 0.75rem 0.5rem;
    justify-content: space-between;
    border-bottom: 0;
  }
  /* Services panel — mobile: flow inline inside the drawer instead of
     anchoring absolute. Surface-2 well sets it apart from the link rows
     above and below, and the 3-column grid collapses to a stack. */
  .site-nav.is-open .services-panel {
    position: static;
    min-width: 0;
    max-width: none;
    background: var(--surface-2);
    border: 0;
    box-shadow: none;
    padding: var(--wp--preset--spacing--20) 0.5rem;
    margin: 0 -0.5rem 0.5rem;
    animation: none;
  }
  .site-nav.is-open .services-panel__cols {
    grid-template-columns: 1fr;
    gap: var(--wp--preset--spacing--20);
  }
  .site-nav.is-open .services-panel__col {
    padding: 0.5rem;
  }
}

/* ----------------------------------------------------------------------
   Email block — used on /kontakt/ as a primary content artefact above the
   contact-cta bookend. Card-like, brand-soft hairline, the email address
   itself rendered as a Plex Mono headline (so it visually reads as
   "machine-checkable" not "marketing prose"). Reuses the existing pill
   component for the Q3-2026-slots affordance.
   ---------------------------------------------------------------------- */
.email-block {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--lg);
  padding: var(--wp--preset--spacing--50);
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--30);
  margin-block: var(--wp--preset--spacing--50);
}
.email-block__label {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin: 0;
}
.email-block__addr {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: clamp(1.25rem, 3vw, 2rem);
  color: var(--brand);
  text-decoration: none;
  word-break: break-all;
}
.email-block__addr:hover,
.email-block__addr:focus-visible {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.25em;
}
.email-block__hint { margin: 0; }

/* ==========================================================================
   Service-page + blog-post patterns
   Selectors used by:
   - patterns/service-ksef.php
   - patterns/service-blueprint.php (Inserter:false fork target)
   - patterns/post-blueprint.php (Inserter:false fork target)
   All rules consume semantic tokens only, so light/dark mode + repalettes
   work without touching this block.
   ========================================================================== */

/* ---------- Hero — trust badges row ----------------------------------- */
.ksef-hero__badges,
.service-hero__badges {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: var(--wp--preset--spacing--40) 0 0;
  padding: 0;
}
.ksef-hero__badges .is-style-pill,
.service-hero__badges .is-style-pill {
  /* The base .is-style-pill (defined earlier) handles the chip look —
     keeping this empty-rule placeholder so it's clear the list items
     are intentionally pills, not raw <li>s. */
}

/* ---------- Pricing packages — 4-card grid + highlight variant ------- */
.ksef-packages {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--wp--preset--spacing--40);
  margin-block: var(--wp--preset--spacing--50);
}
@media (max-width: 1100px) {
  .ksef-packages { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
  .ksef-packages { grid-template-columns: 1fr; }
}
.ksef-package {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--20);
  padding: var(--wp--preset--spacing--40);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--lg);
  overflow: hidden;
  transition: var(--wp--custom--transition--base);
}
.ksef-package:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-card-lifted);
  border-color: var(--brand);
}
/* Recommended-package variant — brand outline + soft inner halo so the
   "Najczęstszy wybór" reads at a glance without screaming. The outline
   is 2px to take up the same place as 1px border, so card grid stays
   visually aligned. */
.ksef-package--highlight {
  border: 2px solid var(--brand);
  background:
    linear-gradient(180deg, var(--brand-soft) 0%, var(--surface) 35%);
  box-shadow: 0 0 0 4px var(--brand-soft);
}
.ksef-package--highlight:hover {
  box-shadow: 0 0 0 4px var(--brand-soft), var(--shadow-card-lifted);
}
.ksef-package__flag {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  padding: 0.25rem 0.625rem;
  background: var(--brand);
  color: var(--surface);
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-radius: var(--wp--custom--radius--pill);
}
.ksef-package__name {
  font-family: var(--wp--preset--font-family--plex-serif);
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.2;
  margin: 0;
  color: var(--ink);
}
.ksef-package__price {
  font-family: var(--wp--preset--font-family--plex-serif);
  font-size: clamp(1.625rem, 2.4vw, 2rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  margin: 0;
  color: var(--brand-strong);
}
.ksef-package__time {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0;
}
.ksef-package__audience {
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--ink-muted);
  margin: var(--wp--preset--spacing--20) 0 0;
}
.ksef-package__includes {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0;
  margin: var(--wp--preset--spacing--30) 0 0;
  font-size: 0.875rem;
  line-height: 1.4;
  color: var(--ink);
}
.ksef-package__includes li {
  position: relative;
  padding-left: 1.25rem;
}
.ksef-package__includes li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0;
  color: var(--success);
  font-weight: 700;
}

/* ---------- Why-me — 6 reason tiles in a 3x2 grid -------------------- */
.ksef-reasons {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--wp--preset--spacing--50);
  padding: 0;
  margin: var(--wp--preset--spacing--50) 0 0;
}
@media (max-width: 900px) { .ksef-reasons { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) { .ksef-reasons { grid-template-columns: 1fr; } }
.ksef-reason {
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--20);
}
.ksef-reason__icon {
  font-size: 1.75rem;
  line-height: 1;
}
.ksef-reason__title {
  font-family: var(--wp--preset--font-family--plex-serif);
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.25;
  margin: 0;
  color: var(--ink);
}
.ksef-reason__desc {
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ink-muted);
  margin: 0;
}

/* ---------- FAQ — native <details>/<summary> with +/− chevron ------- */
.ksef-faq__list {
  margin: var(--wp--preset--spacing--40) 0 0;
}
.ksef-faq__item {
  border-bottom: 1px solid var(--border);
  padding: var(--wp--preset--spacing--40) 0;
}
.ksef-faq__item:first-child { border-top: 1px solid var(--border); }
.ksef-faq__q {
  position: relative;
  display: block;
  list-style: none;          /* Firefox + standards */
  cursor: pointer;
  padding-right: 2.5rem;
  font-family: var(--wp--preset--font-family--plex-serif);
  font-size: clamp(1.0625rem, 1.4vw, 1.25rem);
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink);
}
.ksef-faq__q::-webkit-details-marker { display: none; } /* old WebKit */
.ksef-faq__q::marker { content: ""; }                   /* modern */
.ksef-faq__q::after {
  content: "+";
  position: absolute;
  right: 0;
  top: 0.1em;
  width: 1.625rem;
  height: 1.625rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  font-size: 1.125rem;
  font-weight: 400;
  color: var(--ink-muted);
  background: var(--surface);
  transition: var(--wp--custom--transition--fast);
}
.ksef-faq__item[open] .ksef-faq__q::after {
  content: "−";
  background: var(--brand-soft);
  color: var(--brand-strong);
  border-color: var(--brand);
}
.ksef-faq__a {
  margin-top: var(--wp--preset--spacing--30);
  color: var(--ink-muted);
  line-height: 1.6;
}
.ksef-faq__a p { margin: 0; }

/* ---------- Service-page process steps — 5 items wrap nicely -------- */
/* Override the homepage's 4-col process-step grid for service pages
   that have 5 steps. Force 5 columns at desktop so the row is balanced
   (auto-fit was leaving an awkward 3+2 layout); fall back to auto-fit
   at smaller viewports for graceful wrap. */
.ksef-process .process-steps,
.service-process .process-steps {
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
@media (min-width: 1100px) {
  .ksef-process .process-steps,
  .service-process .process-steps {
    grid-template-columns: repeat(5, 1fr);
  }
}

/* ---------- Service-page sections — anchor headings + hero stack to wide-edge
   The page-service template renders post-content as alignfull→constrained
   so section-bleed backgrounds reach the viewport edge. Each service section
   (.ksef-hero, .ksef-pain, …) is alignwide (1280px) with its own
   layout:constrained, so unaligned children inside it get clamped to
   contentSize (720px) and auto-centered. The cards/grids/columns below are
   alignwide (1280px) — leaving every eyebrow, H2, lead paragraph, and
   button group indented 280px and visually orphaned from the content
   beneath. Re-anchor those children to the wide-size left edge and re-cap
   the hero lead at a sane reading measure. Specificity .ksef-X > element
   is 0,1,1 — beats the WP-injected layout selector at 0,1,0. */
.ksef-hero > h1,
.ksef-hero > p,
.ksef-hero > .wp-block-buttons,
.ksef-hero > ul,
.ksef-pain > p,
.ksef-pain > h2,
.ksef-scope > h2,
.ksef-scope > p:not(.has-text-align-center),
.ksef-scope > .wp-block-buttons:not(.is-content-justification-center),
.ksef-process > p,
.ksef-process > h2,
.ksef-why > p,
.ksef-why > h2,
.ksef-faq > p,
.ksef-faq > h2 {
  max-width: var(--wp--style--global--wide-size, 1280px);
  /* WP's .is-layout-constrained sets margin: auto !important, so we need
     !important here to anchor narrower children (e.g. the hero lead at
     60ch) to the left edge instead of centering them. */
  margin-left: 0 !important;
  margin-right: auto !important;
}
.ksef-hero > p.has-large-font-size {
  /* Re-narrow the lead for reading comfort; left-anchored, not centered. */
  max-width: 60ch;
}
.ksef-hero .wp-block-button > .wp-block-button__link {
  /* Theme default 0.625rem/1.25rem reads as a form button, not a hero CTA. */
  padding-block: 0.875rem;
  padding-inline: 1.5rem;
}

/* ---------- Blog post — meta line ------------------------------------ */
.post-meta {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.8125rem;
  color: var(--ink-faint);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0;
  letter-spacing: 0.04em;
}
.post-meta time {
  color: inherit;
}

/* ---------- Blog post — TL;DR card (riding .is-style-card) ----------- */
/* TL;DR sits inside an .is-style-card group; we override surface to
   brand-soft so it pops as a "summary" on first scroll. */
.post-tldr {
  margin: var(--wp--preset--spacing--50) 0;
  background: var(--brand-soft);
  border-color: var(--brand);
}
.post-tldr p {
  font-size: 1rem;
  line-height: 1.6;
  color: var(--ink);
  margin: 0;
}
.post-tldr .is-style-eyebrow {
  color: var(--brand-strong);
}

/* ---------- Blog post — mid-article internal-link callout ------------ */
.post-internal-cta {
  margin: var(--wp--preset--spacing--50) 0;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-left: 4px solid var(--brand);
}
.post-internal-cta__list {
  list-style: none;
  padding: 0;
  margin: var(--wp--preset--spacing--20) 0 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.post-internal-cta__list a {
  color: var(--brand);
  text-decoration: underline;
  text-underline-offset: 0.25em;
  text-decoration-thickness: 1px;
}
.post-internal-cta__list a:hover {
  color: var(--brand-strong);
  text-decoration-thickness: 2px;
}

/* ---------- Blog post — author byline -------------------------------- */
.post-author {
  margin-top: var(--wp--preset--spacing--60);
  padding-top: var(--wp--preset--spacing--40);
  border-top: 1px solid var(--border);
}
.post-author__card {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--wp--preset--spacing--40);
  align-items: start;
}
@media (max-width: 600px) {
  .post-author__card { grid-template-columns: 1fr; }
}
.post-author__photo {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--surface-3);
  border: 1px solid var(--border);
  display: block;
  object-fit: cover;
}
.post-author__meta {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.post-author__name {
  font-family: var(--wp--preset--font-family--plex-serif);
  font-size: 1.25rem;
  font-weight: 600;
  margin: 0;
  color: var(--ink);
}
.post-author__role {
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  margin: 0;
}
.post-author__bio {
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ink-muted);
  margin: 0.5rem 0 0;
}
.post-author__link {
  align-self: flex-start;
  font-family: var(--wp--preset--font-family--plex-mono);
  font-size: 0.8125rem;
  color: var(--brand);
  text-decoration: none;
  margin-top: 0.25rem;
}
.post-author__link:hover { text-decoration: underline; text-underline-offset: 0.25em; }

/* ---------- Blog post — body sections -------------------------------- */
/* Slightly tighten leading for body paragraphs vs. global so reading
   pace matches an article (vs. a hero). Heading/paragraph hierarchy
   already comes from theme.json. */
.post-body p {
  line-height: 1.65;
  color: var(--ink);
}
.post-body h2 {
  margin-top: var(--wp--preset--spacing--60);
}
.post-body h2:first-of-type {
  margin-top: var(--wp--preset--spacing--50);
}

/* ==========================================================================
   Service-page — Aplikacje webowe i mobilne (Pillar 2 head)
   ----------------------------------------------------------------------------
   Mirrors the .ksef-* component vocabulary so the visual contract stays
   identical across service pillars. New here: the 3-card "axes" grid (per-
   axis pathway: function / vertical / type) which is unique to this pillar.
   When a 3rd service page lands, refactor opportunity: hoist .ksef-* and
   .aplikacje-* into shared .service-* classes.
   ========================================================================== */

/* Hero — reuse the existing .service-hero__badges generic where possible. */
.aplikacje-hero__badges {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: var(--wp--preset--spacing--40) 0 0;
  padding: 0;
}

/* ---------- Three pathway cards — function / vertical / type ---------- */
.aplikacje-axes__grid {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--wp--preset--spacing--40);
  margin-block: var(--wp--preset--spacing--50);
  padding: 0;
}
@media (max-width: 900px) {
  .aplikacje-axes__grid {
    grid-template-columns: 1fr;
  }
}
.aplikacje-axes__card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--lg, 12px);
  padding: var(--wp--preset--spacing--40);
  overflow: hidden;
  transition: border-color 200ms cubic-bezier(0.4, 0, 0.2, 1), transform 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.aplikacje-axes__card:hover {
  border-color: var(--brand);
  transform: translateY(-2px);
}
.aplikacje-axes__card .card-deco {
  position: absolute;
  top: 0;
  right: 0;
  pointer-events: none;
}
.aplikacje-axes__eyebrow {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
  margin: 0;
}
.aplikacje-axes__title {
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.3;
  margin: 0;
  color: var(--ink);
}
.aplikacje-axes__lede {
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--ink-muted);
  margin: 0;
}
.aplikacje-axes__links {
  list-style: none;
  margin: 0.25rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}
.aplikacje-axes__links li {
  font-size: 0.9375rem;
}
.aplikacje-axes__links li::before {
  content: "→ ";
  color: var(--brand);
  margin-right: 0.25rem;
}
.aplikacje-axes__links a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 200ms cubic-bezier(0.4, 0, 0.2, 1), border-color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.aplikacje-axes__links a:hover,
.aplikacje-axes__links a:focus-visible {
  color: var(--brand);
  border-bottom-color: var(--brand);
}
.aplikacje-axes__pending {
  color: var(--ink-faint);
  font-style: italic;
}
.aplikacje-axes__cta {
  margin-top: auto;
  align-self: flex-start;
  font-weight: 600;
  color: var(--brand);
  text-decoration: none;
  font-size: 0.9375rem;
}
.aplikacje-axes__cta:hover,
.aplikacje-axes__cta:focus-visible {
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

/* ---------- Process — 5 numbered steps, vertical list ---------------- */
.aplikacje-process__steps {
  list-style: none;
  margin: var(--wp--preset--spacing--50) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--wp--preset--spacing--40);
}
.aplikacje-process__step {
  display: grid;
  grid-template-columns: 4rem 1fr;
  gap: var(--wp--preset--spacing--30);
  align-items: start;
  padding-bottom: var(--wp--preset--spacing--40);
  border-bottom: 1px solid var(--border);
}
.aplikacje-process__step:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}
.aplikacje-process__num {
  font-size: 1.75rem;
  font-weight: 600;
  color: var(--brand);
  line-height: 1;
}
.aplikacje-process__title {
  font-size: 1.125rem;
  font-weight: 600;
  margin: 0 0 0.5rem;
  color: var(--ink);
}
.aplikacje-process__desc {
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ink-muted);
  margin: 0;
}
@media (max-width: 600px) {
  .aplikacje-process__step {
    grid-template-columns: 1fr;
    gap: 0.5rem;
  }
}

/* ---------- Why-me reasons — 6-card grid ----------------------------- */
.aplikacje-reasons__grid {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--wp--preset--spacing--40);
  margin-block: var(--wp--preset--spacing--50);
  padding: 0;
}
@media (max-width: 900px) {
  .aplikacje-reasons__grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 600px) {
  .aplikacje-reasons__grid {
    grid-template-columns: 1fr;
  }
}
.aplikacje-reasons__card {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: var(--wp--preset--spacing--30);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--wp--custom--radius--md, 8px);
}
.aplikacje-reasons__icon {
  font-size: 1.5rem;
  line-height: 1;
}
.aplikacje-reasons__title {
  font-size: 1rem;
  font-weight: 600;
  margin: 0;
  color: var(--ink);
}
.aplikacje-reasons__desc {
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--ink-muted);
  margin: 0;
}

/* ---------- FAQ — accordion (parallel to .ksef-faq__*) --------------- */
.aplikacje-faq__list {
  margin: var(--wp--preset--spacing--50) 0 0;
}
.aplikacje-faq__item {
  border-bottom: 1px solid var(--border);
}
.aplikacje-faq__item:first-child {
  border-top: 1px solid var(--border);
}
.aplikacje-faq__q {
  list-style: none;
  cursor: pointer;
  padding: var(--wp--preset--spacing--30) 0;
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--ink);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}
.aplikacje-faq__q::-webkit-details-marker { display: none; }
.aplikacje-faq__q::marker { content: ""; }
.aplikacje-faq__q::after {
  content: "+";
  font-size: 1.5rem;
  font-weight: 400;
  color: var(--brand);
  transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1);
  flex-shrink: 0;
}
.aplikacje-faq__item[open] .aplikacje-faq__q::after {
  transform: rotate(45deg);
}
.aplikacje-faq__a {
  padding-bottom: var(--wp--preset--spacing--30);
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--ink-muted);
}

/* ---------- Section content alignment (parallel to .ksef-* alignment) - */
.aplikacje-hero > h1,
.aplikacje-hero > p,
.aplikacje-hero > .wp-block-buttons,
.aplikacje-hero > ul,
.aplikacje-axes > h2,
.aplikacje-axes > p,
.aplikacje-process > p,
.aplikacje-process > h2,
.aplikacje-reasons > p,
.aplikacje-reasons > h2,
.aplikacje-faq > p,
.aplikacje-faq > h2,
.aplikacje-cta > h2,
.aplikacje-cta > p,
.aplikacje-cta > .wp-block-buttons,
.oprogramowanie-criteria > h2,
.oprogramowanie-criteria > p {
  max-width: var(--wp--style--global--content-size, 720px);
}

/* ---------- Reduced motion: kill all hover translations -------------- */
@media (prefers-reduced-motion: reduce) {
  .ksef-package,
  .ksef-package:hover,
  .ksef-faq__q::after,
  .aplikacje-axes__card,
  .aplikacje-axes__card:hover,
  .aplikacje-faq__q::after,
  .oprogramowanie-verticals__card,
  .oprogramowanie-verticals__card:hover {
    transition: none !important;
    transform: none !important;
  }
}

/* ==========================================================================
   Service-page — Oprogramowanie dla firm (Pillar 5 head)
   Reuses .aplikacje-* for hero / process / faq / cta. Three new components:
   .oprogramowanie-verticals__* (9-card grid 3→2→1), .oprogramowanie-compare
   (3-col table, scrollable on mobile), .oprogramowanie-criteria (numbered
   checklist + anti-pattern callout). Hoist into .service-* on next pillar.
   ========================================================================== */

/* 9-vertical industry cards — 3x3 desktop, 2-col tablet, 1-col mobile */
.oprogramowanie-verticals__grid { list-style: none; display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--wp--preset--spacing--40); margin-block: var(--wp--preset--spacing--50); padding: 0; }
@media (max-width: 900px) { .oprogramowanie-verticals__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) { .oprogramowanie-verticals__grid { grid-template-columns: 1fr; } }
.oprogramowanie-verticals__card { display: flex; flex-direction: column; gap: 0.5rem; padding: var(--wp--preset--spacing--30); background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--wp--custom--radius--md, 8px); transition: border-color 200ms cubic-bezier(0.4, 0, 0.2, 1), transform 200ms cubic-bezier(0.4, 0, 0.2, 1); }
.oprogramowanie-verticals__card:hover { border-color: var(--brand); transform: translateY(-2px); }
.oprogramowanie-verticals__icon { font-size: 1.5rem; line-height: 1; }
.oprogramowanie-verticals__title { font-size: 1rem; font-weight: 600; margin: 0; color: var(--ink); }
.oprogramowanie-verticals__desc { font-size: 0.9375rem; line-height: 1.5; color: var(--ink-muted); margin: 0; }
.oprogramowanie-verticals__cta { margin-top: auto; font-size: 0.875rem; font-weight: 600; color: var(--brand); text-decoration: none; }
.oprogramowanie-verticals__cta:hover, .oprogramowanie-verticals__cta:focus-visible { text-decoration: underline; text-underline-offset: 0.25em; }
.oprogramowanie-verticals__pending { margin-top: auto; color: var(--ink-faint); font-style: italic; font-size: 0.875rem; }

/* Comparison table — 3-col, scrollable on mobile */
.oprogramowanie-compare { width: 100%; border-collapse: collapse; margin-block: var(--wp--preset--spacing--40); }
.oprogramowanie-compare th, .oprogramowanie-compare td { padding: var(--wp--preset--spacing--20) var(--wp--preset--spacing--30); text-align: left; border-bottom: 1px solid var(--border); font-size: 0.9375rem; line-height: 1.5; vertical-align: top; }
.oprogramowanie-compare th { background: var(--surface-2); color: var(--ink); font-weight: 600; font-size: 0.875rem; text-transform: uppercase; letter-spacing: 0.04em; }
.oprogramowanie-compare th a { color: var(--brand); text-decoration: none; border-bottom: 1px dotted var(--brand); }
.oprogramowanie-compare th a:hover, .oprogramowanie-compare th a:focus-visible { text-decoration: underline; border-bottom: 1px solid var(--brand); }
.oprogramowanie-compare td:first-child { font-weight: 600; color: var(--ink); }
.oprogramowanie-compare tbody tr:hover { background: var(--surface-2); }
@media (max-width: 720px) {
  .oprogramowanie-compare { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; min-width: 0; }
  .oprogramowanie-compare table, .oprogramowanie-compare thead, .oprogramowanie-compare tbody { min-width: 600px; }
}

/* Criteria checklist — numbered list + anti-pattern callout */
.oprogramowanie-criteria__list { list-style: none; counter-reset: criteria; margin: var(--wp--preset--spacing--40) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--wp--preset--spacing--40); }
.oprogramowanie-criteria__item { position: relative; padding-left: 3.5rem; counter-increment: criteria; }
.oprogramowanie-criteria__item::before { content: counter(criteria); position: absolute; left: 0; top: 0; width: 2.5rem; height: 2.5rem; display: grid; place-items: center; background: var(--brand-soft); color: var(--brand-strong); border-radius: 50%; font-weight: 600; font-size: 1.125rem; }
.oprogramowanie-criteria__item strong { display: block; font-size: 1.0625rem; color: var(--ink); margin-bottom: 0.25rem; }
.oprogramowanie-criteria__item p { font-size: 0.9375rem; line-height: 1.6; color: var(--ink-muted); margin: 0; }
.oprogramowanie-criteria__antipattern { margin-top: var(--wp--preset--spacing--40); padding: var(--wp--preset--spacing--30); border-left: 3px solid var(--warning); background: var(--surface-2); font-size: 0.9375rem; line-height: 1.6; color: var(--ink-muted); border-radius: 0 var(--wp--custom--radius--md, 8px) var(--wp--custom--radius--md, 8px) 0; }
@media (max-width: 600px) {
  .oprogramowanie-criteria__item { padding-left: 0; padding-top: 3rem; }
  .oprogramowanie-criteria__item::before { left: 0; }
}
