/* Bigger points for the Home hero's Sphere only (2026-09 review). The
   colour/brightness part of this same review used to live here too (an
   `html:root` override making Home's Sphere brighter than every other
   page's), but per "все анимации по цвету и яркости сделай как сфера" that
   palette is now network/styles/variables.css's own shared default - every
   component on every page reads it, not just this one - so overriding it
   again here would be dead weight, not a real difference. Only the point
   radius stays page-specific: a deliberate size choice for this hero's own
   full-height visual weight, unrelated to colour/brightness, still needs
   the same `html:root` (not bare `:root`) treatment documented below.
   sphere.js reads `--network-point-radius` ONCE via
   `getComputedStyle(document.documentElement)` (its own comment: "every
   sphere instance shares one palette") - a CSS custom property set on a
   descendant never reaches back up to change `:root`'s own resolved
   value, only inheriting back down, so nothing scoped more narrowly
   than `:root` itself would ever be seen.
   `html:root`, not bare `:root` - same specificity-tie problem as
   `.hero .hero-graphic` (hero.css, see its own comment): the network
   library's own `:root` defaults (network/styles/variables.css) are
   linked from inside hero.html's body, which loads AFTER this
   `extra_css` block's `<head>` link, so an equal-specificity plain
   `:root` here would lose that cascade tie and never actually apply.
   The extra `html` type selector breaks the tie unconditionally. */
html:root {
  --network-point-radius: 1.9;
}

/* "Czym się zajmujemy" - every card is the same size (equal 1fr columns).
   With 5 cards and 3 columns, the last row holds 2 cards at their natural
   width instead of stretching to fill the row - plain CSS Grid already
   leaves that 3rd column empty rather than growing the other 2 items. */
.services-mosaic {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* Extra row-gap keeps the floating icon badge (see .service-card-icon)
     clear of the card above it. */
  gap: var(--space-6) var(--space-4);
}

@media (max-width: 991.98px) {
  .services-mosaic {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 767.98px) {
  .services-mosaic {
    grid-template-columns: 1fr;
  }
}

/* "Jak pomagamy Twojej firmie" - editorial split: a short positioning
   statement on the left, 4 results as a numbered list on the right,
   divided by rules instead of individual bordered cards. */
.value-split {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--space-8);
}

.value-split-intro h2 {
  font-size: var(--fs-3xl);
  margin: var(--space-3) 0 var(--space-4);
}

.value-split-statement {
  color: var(--color-text-secondary);
  font-size: var(--fs-lg);
  max-width: 26rem;
  margin: 0;
  /* See .section-title-description (section-title.css) for why. */
  text-wrap: balance;
}

.value-split-intro {
  display: flex;
  flex-direction: column;
}

.value-stats {
  margin-top: var(--space-6);
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4);
}

/* Decorative DNA Helix animation under the stat cards, laid on its side.
   dna-helix.js draws a fixed-proportion (~1:2 width:height) upright helix,
   fitted "contain"-style into whatever box its own SVG root measures
   (static/network/components/dna-helix.js) - via `clientWidth`/
   `clientHeight`, which (unlike `getBoundingClientRect()`) ignore CSS
   `transform`, precisely so a plain `rotate(90deg)` on the SVG can turn it
   sideways without the component seeing a distorted/mismatched viewBox.
   `container-type: size` on this wrapper turns on container query units,
   which is what makes the swap work for a FLUID width: the SVG is given a
   portrait box (`100cqb` wide - this wrapper's own height; `100cqi` tall -
   this wrapper's own, fluid, width) so dna-helix.js draws a normal
   upright helix that already fills that portrait box edge to edge, then
   `rotate(90deg)` lays the whole already-correct shape on its side.
   Because the fixed 1:2 aspect never stretches to fully cover a mismatched
   box (contain, not cover - see dna-helix.js's own docstring), the
   rotated helix's drawn LENGTH is capped at ~1.64x the SVG's OWN pre-
   rotation width (0.82 contain margin x HELIX_ASPECT 2, both in
   dna-helix.js), and `aspect-ratio: 2 / 1` on this wrapper is what makes
   that width track this column's fluid width instead of a fixed rem
   value (see below). Giving the SVG a box sized to exactly this
   wrapper's own box (100cqb/100cqi) would therefore only ever draw at
   ~82% of this wrapper's own width (0.82 margin x the 2:1 aspect
   cancelling out - see this rule's git history for that version). To
   reach edge to edge instead, the SVG's box is inflated by 1/0.82
   (~122%) on both axes - same aspect, just scaled up - which scales the
   0.82-margined DRAWN content by that same factor, exactly cancelling
   the margin (0.82 x 1.22 = 1.0): the helix itself now draws flush with
   this wrapper's edges, and only the SVG's own already-blank margin
   (nothing dna-helix.js ever draws into) spills past the wrapper's own
   box - `overflow: hidden` below discards that empty spillover, not any
   visible dot/line. The `mask-image` fade (also below) is a separate,
   deliberate effect on top - not a fix for anything above - so the
   helix's own end points/lines dissolve into the background before
   reaching this wrapper's actual edge, instead of ending on a hard,
   very visible boundary.
   No card chrome of its own (no background/border/shadow) - it just sits
   directly on .section-alt's own background, dots floating loose the same
   way .value-list's icons/rules do on the right, not another boxed card
   next to .value-stat's two.
   Network Graphics System components default to light-on-dark colour
   tokens (static/network/README.md), which is why the internal showcase
   always previews them on a dark stage - dna-helix.css's own rules
   (`.dna-point`, `.dna-strand-line`, `.dna-rung-gradient-stop`) already
   read colour purely from --network-point-rgb/--network-line-rgb, so
   overriding both locally (nothing else in dna-helix.js/css is
   hardcoded) is enough to make the whole shape - points AND the
   strand/rung lines connecting them - read clearly against this
   section's actual light background. (An earlier version of this rule
   only overrode --network-point-rgb, leaving every connecting line at
   the library's default pale-on-dark colour - functionally invisible
   against a light background.)
   margin: auto 0 (not a fixed top margin) is what centres it in the
   leftover space: .value-split-intro is a flex column stretched taller
   than its own content (the grid row matches .value-list's height, see
   above), and auto margins on a flex item absorb the container's free
   space along the main axis - splitting it evenly above/below centres
   the element in whatever leftover room there is below the stat cards,
   instead of sitting flush right under them. On the stacked mobile
   layout there's no leftover space to absorb, so this is a no-op there -
   it just sits right after the stat cards, which is fine at that width. */
.value-stats-dna {
  position: relative;
  margin: auto 0;
  align-self: center; /* with an explicit width below overriding .value-split-intro's default stretch, this is what keeps it centred instead of flush left */
  width: 88%; /* a bit narrower than the column - shrinks height to match (aspect-ratio below), which is what actually buys clearance from the stat cards above: this box's own height is what auto-margin has to fit into the leftover space */
  aspect-ratio: 9 / 2; /* 4.5/1 - another 1.5x narrower than 3/1, chained from the original 2/1. Must stay equal to dna-helix.js's own HELIX_ASPECT (see that file) - the component's fixed-shape "contain" fit only reaches this box's own edges (and therefore the mask fade below) when its intrinsic length:thickness ratio matches this container's own ratio; any mismatch leaves the drawn strand short of the edges, silently making the mask fade invisible (nothing there to fade) rather than erroring. */
  max-height: 18rem; /* generous ultra-wide-column safety cap only - well above what `aspect-ratio` resolves to at any realistic column width, so it never fights the ratio itself (a tighter cap here previously clipped the drawn length far short of the "roughly 80-90% of width" target above) */
  container-type: size;
  overflow: hidden; /* discards the oversized SVG's own blank margin - see comment above, not a crop of any visible dot/line */
  /* Soft fade at both ends instead of a hard cutoff - see comment above.
     A flat fully-transparent band first (0-8%/92-100%), THEN a ramp
     (8-24%/76-92%): the strand endpoints are a fixed, full-opacity,
     oversized accent (dna-helix.js's ENDPOINT_ALPHA/ENDPOINT_SIZE_SCALE -
     deliberately NOT faded by the component itself) sitting right at this
     box's own edge (see comment above - the 122% inflation puts drawn
     content flush with the edge), so landing them partway up a ramp
     still left them visibly lit; a flat zero-opacity band guarantees
     they're fully gone regardless of a few px of rounding, and the wider
     ramp past it dissolves the rest of the strand gradually rather than
     revealing a new hard edge one step in.
     -webkit-mask-image is still required for Safari (unprefixed
     `mask-image` alone isn't enough there as of this writing). */
  -webkit-mask-image: linear-gradient(to right, transparent 0%, transparent 8%, #000 24%, #000 76%, transparent 92%, transparent 100%);
  mask-image: linear-gradient(to right, transparent 0%, transparent 8%, #000 24%, #000 76%, transparent 92%, transparent 100%);
  --network-point-rgb: var(--bs-primary-rgb); /* --color-primary - default --network-point-rgb (variables.css) is a pale light-on-dark blue, invisible against this section's light background */
  --network-line-rgb: var(--bs-primary-rgb); /* same override, same reason */
}

.value-stats-dna .network-dna-helix {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 122cqb; /* 100cqb / 0.82 - see comment above */
  height: 122cqi; /* 100cqi / 0.82 - see comment above */
  transform: translate(-50%, -50%) rotate(90deg);
}

.value-stat {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-4);
  background-color: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}

.value-stat-top {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.value-stat-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-pill);
  background-color: rgba(var(--bs-primary-rgb), 0.1);
  color: var(--color-primary);
  font-size: 1.375rem;
}

.value-stat-number {
  font-size: var(--fs-2xl);
  font-weight: var(--fw-bold);
  color: var(--color-primary);
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.value-stat-label {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--color-text-secondary);
}

.value-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.value-list-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-4);
  border-radius: var(--radius-md);
  transition: background-color var(--transition-base), box-shadow var(--transition-base), transform var(--transition-base);
}

.value-list-item + .value-list-item {
  margin-top: var(--space-2);
}

.value-list-item:hover {
  background-color: var(--color-bg);
  box-shadow: var(--shadow-sm);
  transform: translateX(var(--space-2));
}

/* Icon badge - same "white pill on tinted section" language as
   .service-card-icon, but an inline rounded square instead of a floating
   circle, and its own hover fill (row hover, not card hover) instead of
   sitting half outside a card edge. */
.value-list-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: var(--radius-md);
  background-color: var(--color-bg);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
  color: var(--color-primary);
  transition: background-color var(--transition-base), border-color var(--transition-base), color var(--transition-base), transform var(--transition-base);
}

.value-list-item:hover .value-list-icon {
  background-color: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
  transform: scale(1.08);
}

.value-list-icon svg {
  width: 1.75rem;
  height: 1.75rem;
}

.value-list-body h3 {
  font-size: var(--fs-lg);
  margin: 0 0 var(--space-2);
}

.value-list-body p {
  color: var(--color-text-secondary);
  margin: 0;
  max-width: 34rem;
}

@media (max-width: 767.98px) {
  .value-split {
    grid-template-columns: 1fr;
    gap: var(--space-5);
  }
}

/* .value-split's 5fr intro column is a fixed ~273px here (Bootstrap's
   .container is a flat 720px through the whole md tier, not fluid) - too
   narrow for the two stat cards' combined min-content (~340px), which
   only avoided forcing page-wide overflow (like the 349.98 case below) by
   spilling into the column gap. Stack them instead of riding right at
   that edge. Below 768 .value-split is already full-width (no split, see
   above) with plenty of room for the 2-column row; at 992+ .container
   jumps to 960px, giving the intro column enough space - so this only
   targets the cramped md tier in between. */
@media (min-width: 768px) and (max-width: 991.98px) {
  .value-stats {
    grid-template-columns: 1fr;
  }
}

/* Below this, the two stat cards' fixed icon+gap+padding plus the bold
   fs-2xl count text no longer fit side by side in the available width
   (min-content overflows the viewport - WCAG 1.4.10 reflow requires no
   horizontal scroll down to 320px) - stack them like a single-column
   .value-list-item instead of letting the row force page-wide overflow. */
@media (max-width: 349.98px) {
  .value-stats {
    grid-template-columns: 1fr;
  }
}

/* Mesh as a full-section ambient background ("Hosting, na którym można
   polegać" below, and "Serwery VPS...") - the shared .section-has-mesh-bg
   / .section-mesh-bg shape now lives in components/mesh-section.css (a
   second page started reusing it, doc09 "не копировать CSS между
   страницами" - see that file's own comment for the mechanics). */

/* .hosting-perks-strip (what every plan in a grid includes identically)
   moved to components/hosting-plan-card.css - G10 needed it too (doc09
   "не копировать CSS между страницами", same reasoning solution-table.css
   was already promoted for). */

/* "Serwery VPS..." section intro - the description otherwise fits on one
   line at typical desktop widths (~658px vs the .section-title block's
   672px max-width); this narrows it just enough to force the wrap onto
   "gdy hosting współdzielony..." as its own second line, matching the
   two-line rhythm the other section intros land on naturally. */
.section-vps .section-title-description {
  max-width: 345px;
  margin: 0 auto;
  /* Override text-wrap: balance (section-title.css) - balance would
     re-run its own line-count search against this max-width and land on
     3 lines instead of the 2 this width is tuned for; plain wrap keeps
     the intended break. */
  text-wrap: wrap;
}
