/* ZeroSite base stylesheet.
 *
 * Structure for every block, in neutral form: enough that a page is correct and
 * readable on its own, with nothing that belongs to one theme's personality.
 * A layout theme (styles/themes/<id>.css) is concatenated after this at build
 * time and overrides from here.
 *
 * Consumes the CSS variables site.css emits (colours, fonts, radius), so a
 * colour preset repaints every theme without any theme knowing about it. */

*, *::before, *::after { box-sizing: border-box; }

:root {
  /* How wide running text is allowed to get. Not in site.css because it's a
     legibility constant, not a brand choice. */
  --zs-measure: 46rem;

  /* Band colours, resolved once here so a band can redeclare the palette for
     everything inside it without repainting itself: these tokens compute
     against the root's palette, the redeclarations only reach descendants.
     A theme overrides these to say what its own "dark" actually is. */
  --zs-tone-soft: var(--zs-color-surface);
  --zs-tone-dark: var(--zs-color-secondary);
  --zs-tone-brand: var(--zs-color-primary);
  --zs-tone-on-dark: #f8fafc;
  /* The accent, lightened enough to read on a dark band. A band can't derive
     this itself: redeclaring --zs-color-primary in terms of --zs-color-primary
     is a cycle, and CSS drops the whole declaration. */
  --zs-tone-accent-on-dark: color-mix(in srgb, var(--zs-color-primary) 40%, #fff);
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: var(--zs-font-body);
  font-size: var(--zs-font-size-base);
  line-height: 1.75;
  color: var(--zs-color-text);
  background: var(--zs-color-background);
  word-break: thai;
  overflow-wrap: break-word;
}

img, video { max-width: 100%; height: auto; }

h1, h2, h3, h4, h5, h6 {
  font-family: var(--zs-font-heading);
  line-height: 1.35;
  color: var(--zs-color-secondary);
  margin: 1.5em 0 0.5em;
}
h1 { font-size: 2.25rem; margin-top: 0.5em; }
h2 { font-size: 1.6rem; }
h3 { font-size: 1.3rem; }
h4 { font-size: 1.1rem; }

a { color: var(--zs-color-primary); }
a:hover { opacity: 0.85; }

.zs-container {
  max-width: var(--zs-container-max);
  margin: 0 auto;
  padding: 0 1.25rem;
}

/* ---------- Header ---------- */
.zs-header {
  border-bottom: 1px solid color-mix(in srgb, var(--zs-color-muted) 25%, transparent);
  background: var(--zs-color-background);
}
.zs-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 4rem;
  position: relative;
}
.zs-logo { display: inline-flex; align-items: center; text-decoration: none; }
.zs-logo-text {
  font-family: var(--zs-font-heading);
  font-weight: 700;
  font-size: 1.35rem;
  color: var(--zs-color-secondary);
}
.zs-nav-list {
  list-style: none;
  display: flex;
  gap: 1.5rem;
  margin: 0;
  padding: 0;
}
.zs-nav-list a {
  text-decoration: none;
  color: var(--zs-color-text);
  font-weight: 500;
}
.zs-nav-list a:hover { color: var(--zs-color-primary); }

/* mobile nav (no JS — checkbox toggle) */
.zs-nav-toggle { display: none; }
.zs-nav-burger { display: none; cursor: pointer; padding: 0.5rem; }
.zs-nav-burger span {
  display: block;
  width: 22px;
  height: 2px;
  margin: 5px 0;
  background: var(--zs-color-secondary);
}
@media (max-width: 720px) {
  .zs-nav-burger { display: block; }
  .zs-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--zs-color-background);
    border-bottom: 1px solid color-mix(in srgb, var(--zs-color-muted) 25%, transparent);
    padding: 1rem 1.25rem;
    z-index: 50;
  }
  .zs-nav-toggle:checked ~ .zs-nav { display: block; }
  .zs-nav-list { flex-direction: column; gap: 0.75rem; }
}

/* ---------- Content ---------- */
main { min-height: 60vh; padding: 2rem 0 4rem; }

/* A post is an essay: one column, capped at a comfortable measure. */
.zs-article { max-width: var(--zs-measure); margin: 0 auto; }
/* Scoped away from pages: this selector is more specific than .zs-article-page
   below, so without the :not it silently re-caps a page at 56rem and the
   sections inside it stop lining up with the full-bleed bands around them. */
.zs-width-wide .zs-article:not(.zs-article-page) {
  max-width: calc(var(--zs-measure) + 10rem);
}

/* A page is a layout, not an essay. Capping the whole article was quietly
   overruling the site's container width for everything below the header: a
   six-item service grid had 46rem to work with while the theme was set to
   1280px, so it rendered as three thumbnails in a narrow strip with dead space
   on both sides. The cap belongs on the running text, not on the layout. */
.zs-article-page { max-width: none; }

/* So the measure moves down to the prose blocks themselves, wherever they sit —
   loose in the article or inside a section — and centres in whatever box holds
   them. Composite blocks (grids, bands, media strips) are deliberately absent
   from this list: filling their container is the whole point of them. */
/* The page's own title is a sibling of .zs-content, not a child of it, so it
   needs naming separately — without this it was the one line on the page with
   no cap at all, running the full container width while every paragraph under
   it stopped at the measure. */
.zs-article-page > h1,
.zs-article-page .zs-content > :is(p, h1, h2, h3, h4, h5, h6, ul, ol, blockquote, pre, .zs-figure, .zs-table-wrap),
.zs-article-page .zs-section-stack > .zs-section-inner > :is(p, h1, h2, h3, h4, h5, h6, ul, ol, blockquote, pre, .zs-figure, .zs-table-wrap) {
  max-width: var(--zs-measure);
  margin-inline: auto;
}
/* Except where the author asked for edge-to-edge — a photo strip, a map. */
.zs-section-content-full > .zs-section-inner > * { max-width: none; }

.zs-content p { margin: 0 0 1.1em; }
.zs-content ul, .zs-content ol { padding-left: 1.5rem; margin: 0 0 1.1em; }
.zs-content blockquote {
  margin: 1.5em 0;
  padding: 0.5em 1.25em;
  border-left: 4px solid var(--zs-color-primary);
  background: var(--zs-color-surface);
  border-radius: 0 var(--zs-radius) var(--zs-radius) 0;
}
.zs-content pre {
  background: var(--zs-color-secondary);
  color: #f1f5f9;
  padding: 1rem 1.25rem;
  border-radius: var(--zs-radius);
  overflow-x: auto;
  font-size: 0.9em;
}
.zs-content code { font-family: ui-monospace, monospace; }
.zs-content p code {
  background: var(--zs-color-surface);
  padding: 0.15em 0.4em;
  border-radius: 4px;
  font-size: 0.9em;
}

.zs-figure { margin: 1.75em 0; }
.zs-figure img, .zs-figure video {
  border-radius: var(--zs-radius);
  display: block;
  margin: 0 auto;
}
.zs-figure figcaption {
  text-align: center;
  font-size: 0.875rem;
  color: var(--zs-color-muted);
  margin-top: 0.5rem;
}

.zs-table-wrap { overflow-x: auto; margin: 1.5em 0; }
.zs-table-wrap table { border-collapse: collapse; width: 100%; }
.zs-table-wrap th, .zs-table-wrap td {
  border: 1px solid color-mix(in srgb, var(--zs-color-muted) 30%, transparent);
  padding: 0.5rem 0.75rem;
  text-align: left;
}
.zs-table-wrap th { background: var(--zs-color-surface); }

/* ══════════ Composite layout blocks ══════════
   These lay themselves out and collapse to a single column on small screens, so
   a page built from them is responsive without any per-device settings. */

/* Break out of the article's reading column — sections span the page. */
.zs-hero,
.zs-cards-section,
.zs-imagetext,
.zs-ctaband {
  margin: 2.5em 0;
}

/* ---------- Hero ---------- */
.zs-hero-title {
  font-size: clamp(2.1rem, 1.2rem + 3.6vw, 4rem);
  margin: 0 0 0.35em;
  line-height: 1.1;
  letter-spacing: -0.025em;
}
.zs-hero-sub {
  font-size: clamp(1.05rem, 1rem + .35vw, 1.25rem);
  color: var(--zs-color-muted);
  margin: 0 0 1.8em;
  max-width: 40rem;
}
.zs-hero-center { text-align: center; }
.zs-hero-center .zs-hero-sub { margin-left: auto; margin-right: auto; }
.zs-hero-actions {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
}
.zs-hero-center .zs-hero-actions { justify-content: center; }
.zs-hero-right .zs-hero-actions { justify-content: flex-end; }

/* A hero carrying its own photo. The picture is a background rather than an
   <img> because the text has to sit on top of it and stay readable at every
   width — an overlay over a background does that with no positioning, and the
   image is decorative here, so nothing is lost from the document. */
.zs-hero-bg {
  position: relative;
  background-size: cover;
  background-position: center;
  isolation: isolate;
  padding-block: clamp(4.5rem, 2rem + 9vw, 9rem);
  display: flex;
  align-items: center;
}
.zs-hero-bg::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    180deg,
    rgb(2 6 23 / var(--zs-hero-veil-top, .55)),
    rgb(2 6 23 / var(--zs-hero-veil-bottom, .72))
  );
}
.zs-hero-overlay-light { --zs-hero-veil-top: .25; --zs-hero-veil-bottom: .42; }
.zs-hero-overlay-medium { --zs-hero-veil-top: .5; --zs-hero-veil-bottom: .68; }
.zs-hero-overlay-strong { --zs-hero-veil-top: .7; --zs-hero-veil-bottom: .85; }
/* A photo hero is edge-to-edge whatever it's wrapped in: it breaks out the same
   way a full-bleed section does, which is a no-op when the section already did
   it and the escape hatch when the author left the section boxed. */
.zs-hero-bg {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
  margin-block: 0;
}
.zs-hero-bg > .zs-hero-body {
  position: relative;
  width: 100%;
  max-width: var(--zs-container-max);
  margin-inline: auto;
  padding-inline: 1.25rem;
}
.zs-hero-h-tall { min-height: 70vh; }
.zs-hero-h-full { min-height: 100svh; }

.zs-hero-media { margin-bottom: 1.75rem; }
.zs-hero-media img {
  width: 100%;
  border-radius: var(--zs-radius);
  aspect-ratio: 21/9;
  object-fit: cover;
  display: block;
}
@media (max-width: 720px) {
  .zs-hero-media img { aspect-ratio: 16/10; }
}

/* ---------- Cards ---------- */
.zs-section-title {
  text-align: center;
  margin: 0 0 1.2em;
}
.zs-cards {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(var(--cols, 3), 1fr);
}
.zs-cards-2 { --cols: 2; }
.zs-cards-3 { --cols: 3; }
.zs-cards-4 { --cols: 4; }
@media (max-width: 900px) {
  .zs-cards-3, .zs-cards-4 { --cols: 2; }
}
@media (max-width: 640px) {
  .zs-cards { --cols: 1; }
}
.zs-card {
  background: var(--zs-color-surface);
  border-radius: var(--zs-radius);
  padding: 1.4rem;
}
.zs-card h3 { margin: 0 0 0.4em; font-size: 1.05rem; }
.zs-card p { margin: 0; color: var(--zs-color-muted); font-size: 0.95rem; }

/* ---------- Image + text ---------- */
.zs-imagetext {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2rem;
  align-items: center;
}
/* No picture yet — a template ships with the image slot empty, and half a grid
   is worse than no grid: the text stayed in a narrow column with a blank half
   beside it. One column, measured like any other prose, until an image lands. */
.zs-imagetext:not(:has(.zs-imagetext-media)) {
  grid-template-columns: 1fr;
}
.zs-imagetext:not(:has(.zs-imagetext-media)) .zs-imagetext-body {
  max-width: var(--zs-measure);
}
/* Source order puts the image first so it leads when stacked on mobile;
   on desktop, "right" simply moves it across. */
.zs-imagetext-right .zs-imagetext-media { order: 2; }
.zs-imagetext-media img {
  width: 100%;
  border-radius: var(--zs-radius);
  aspect-ratio: 4/3;
  object-fit: cover;
  display: block;
}
.zs-imagetext-body h2 { margin-top: 0; }
.zs-imagetext-body p { color: var(--zs-color-muted); }
@media (max-width: 720px) {
  .zs-imagetext { grid-template-columns: 1fr; gap: 1.25rem; }
  .zs-imagetext-right .zs-imagetext-media { order: 0; }
}

/* ---------- CTA band ---------- */
.zs-ctaband {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  background: var(--zs-color-primary);
  color: #fff;
  border-radius: var(--zs-radius);
  padding: 2rem 2.25rem;
}
.zs-ctaband h2 { color: #fff; margin: 0 0 0.3em; }
.zs-ctaband p { margin: 0; color: rgb(255 255 255 / 0.85); }
.zs-btn-invert {
  background: #fff;
  color: var(--zs-color-primary);
  white-space: nowrap;
}
@media (max-width: 640px) {
  .zs-ctaband { padding: 1.5rem; }
}

/* ---------- Spacer ---------- */
.zs-spacer-sm { height: 1.5rem; }
.zs-spacer-md { height: 3rem; }
.zs-spacer-lg { height: 5rem; }

/* ---------- FAQ ---------- */
.zs-faq {
  border: 1px solid color-mix(in srgb, var(--zs-color-muted) 30%, transparent);
  border-radius: var(--zs-radius);
  margin: 0.75em 0;
  background: var(--zs-color-surface);
}
.zs-faq summary {
  cursor: pointer;
  padding: 0.85em 1.1em;
  font-weight: 600;
  font-family: var(--zs-font-heading);
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.zs-faq summary::-webkit-details-marker { display: none; }
.zs-faq summary::after {
  content: "+";
  font-size: 1.25em;
  line-height: 1;
  color: var(--zs-color-primary);
  transition: transform 150ms ease;
}
.zs-faq[open] summary::after { transform: rotate(45deg); }
.zs-faq-answer {
  padding: 0 1.1em 0.95em;
  color: var(--zs-color-text);
}

/* ---------- CTA ---------- */
.zs-cta { margin: 1.75em 0; }
.zs-cta-center { text-align: center; }
.zs-cta-left { text-align: left; }
.zs-cta-right { text-align: right; }

/* ---------- Embed (click-to-play poster, no third-party JS) ---------- */
.zs-embed-link {
  position: relative;
  display: block;
  border-radius: var(--zs-radius);
  overflow: hidden;
}
.zs-embed-link img {
  width: 100%;
  aspect-ratio: 16/9;
  object-fit: cover;
  display: block;
}
.zs-embed-play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  color: #fff;
  background: rgb(0 0 0 / 0.35);
  transition: background 150ms ease;
}
.zs-embed-link:hover .zs-embed-play { background: rgb(0 0 0 / 0.5); }
.zs-embed-fallback { word-break: break-all; }

/* ---------- Breadcrumbs ---------- */
.zs-breadcrumbs { font-size: 0.875rem; margin-bottom: 1rem; }
.zs-breadcrumbs ol {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin: 0;
  padding: 0;
  color: var(--zs-color-muted);
}
.zs-breadcrumbs li + li::before { content: "›"; margin: 0 0.4rem; }
.zs-breadcrumbs a { color: var(--zs-color-muted); text-decoration: none; }
.zs-breadcrumbs a:hover { color: var(--zs-color-primary); }

/* ---------- Posts ---------- */
.zs-post-meta { color: var(--zs-color-muted); font-size: 0.9rem; }
.zs-cover img { width: 100%; }

.zs-list-header { text-align: center; margin-bottom: 2.5rem; }
.zs-post-grid { display: grid; gap: 1.5rem; }
.zs-postlist-cards .zs-post-grid {
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.zs-post-card {
  background: var(--zs-color-surface);
  border-radius: var(--zs-radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.zs-postlist-list .zs-post-card { flex-direction: row; gap: 1rem; }
.zs-post-card-img img {
  width: 100%;
  aspect-ratio: 16/9;
  object-fit: cover;
  display: block;
}
.zs-postlist-list .zs-post-card-img { flex: 0 0 220px; }
.zs-post-card-body { padding: 1.25rem; }
.zs-post-card h2 { margin: 0 0 0.5rem; font-size: 1.15rem; }
.zs-post-card h2 a { color: var(--zs-color-secondary); text-decoration: none; }
.zs-post-card h2 a:hover { color: var(--zs-color-primary); }
.zs-post-card p { margin: 0 0 0.5rem; font-size: 0.925rem; }

.zs-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  margin-top: 3rem;
  color: var(--zs-color-muted);
}
.zs-pagination a { text-decoration: none; font-weight: 500; }

/* ---------- Buttons ---------- */
.zs-btn {
  display: inline-block;
  background: var(--zs-color-primary);
  color: #fff;
  padding: 0.65rem 1.5rem;
  border-radius: var(--zs-radius);
  text-decoration: none;
  font-weight: 600;
}
.zs-btn:hover { opacity: 0.9; }

/* The outlined companion to the primary action. Declared after .zs-btn on
   purpose: same specificity, so source order is what decides. */
.zs-btn-ghost {
  background: transparent;
  color: currentColor;
  border: 1px solid color-mix(in srgb, currentColor 45%, transparent);
}
.zs-btn-ghost:hover {
  background: color-mix(in srgb, currentColor 12%, transparent);
  opacity: 1;
}

/* ---------- Footer ---------- */
.zs-footer {
  border-top: 1px solid color-mix(in srgb, var(--zs-color-muted) 25%, transparent);
  background: var(--zs-color-surface);
  padding: 2.5rem 0;
  margin-top: 2rem;
}
.zs-footer-inner { display: grid; gap: 1.5rem; }
.zs-footer .zs-nav-list {
  display: grid;
  grid-template-columns: repeat(var(--zs-footer-columns), 1fr);
  gap: 0.5rem 2rem;
}
.zs-footer .zs-nav-list a { font-weight: 400; font-size: 0.925rem; }
.zs-copyright { color: var(--zs-color-muted); font-size: 0.875rem; margin: 0; }

/* ---------- 404 ---------- */
.zs-404 { text-align: center; padding: 4rem 0; }
.zs-404 h1 { font-size: 5rem; margin: 0; }

/* ---------- Sections ---------- */
/* A section is a band of the page holding blocks. Its layout options are
   classes here rather than generated per page, so they cost nothing per page
   and stay consistent across the site; only the free-form Style tab values
   compile into per-page rules. */
.zs-section { --zs-section-gap: 1.25rem; }
.zs-section-inner { display: flex; flex-direction: column; gap: var(--zs-section-gap); }

/* Boxed is a pass-through: the section sits inside the page's container and
   article, which already set the width and the side padding. Adding our own
   would inset the text a second time and shift every page that got wrapped
   into a section automatically. */

/* Full has to break OUT of those ancestors — a child can't be wider than its
   parent, so "full width" is only reachable by pulling the element back to the
   viewport's edges. Margins rather than a positioned left/right offset, so the
   section still takes part in normal vertical flow. */
.zs-section-full {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
}
/* 100vw counts the scrollbar's width, so a full-bleed section is a few pixels
   wider than what you can see and the page picks up a horizontal scrollbar.
   Clipping the overflow at the root is the cheap fix; it doesn't break sticky
   positioning the way overflow on <body> does. */
html { overflow-x: clip; }

/* With the section itself at viewport width, the content inside it either goes
   along or comes back to the page's normal width. Boxed is the default: a band
   of colour edge to edge with the text still lining up with everything above
   it, which is what a full-bleed section is almost always for. */
.zs-section-full > .zs-section-inner { padding: 0 1.25rem; }
.zs-section-full.zs-section-content-boxed > .zs-section-inner {
  max-width: var(--zs-container-max);
  margin-inline: auto;
}
/* Content set to full means full: the side padding above is the guard that
   keeps text off the screen edge, but choosing this explicitly is asking for
   edge-to-edge (a photo strip, a map) — so no padding to quietly re-inset it. */
.zs-section-full.zs-section-content-full > .zs-section-inner { padding: 0; }

/* ---------- Section tone: the bands a page is built from ----------
   A page reads as designed when its sections alternate rather than running as
   one uninterrupted sheet. Each tone repaints the palette for its own subtree,
   so everything inside — headings, muted captions, cards, buttons — follows
   without any block knowing which band it landed in. */
.zs-section-band {
  padding-block: clamp(3rem, 1.5rem + 5vw, 6rem);
  color: var(--zs-color-text);
  background: var(--zs-band-bg);
}
/* The band supplies its own vertical space, so the blocks inside it shouldn't
   also push the usual gap against its padding. */
.zs-section-band > .zs-section-inner > :first-child { margin-top: 0; }
.zs-section-band > .zs-section-inner > :last-child { margin-bottom: 0; }

.zs-section-tone-soft { --zs-band-bg: var(--zs-tone-soft); }
/* Surface is the tint that cards sit on; inside a tinted band they'd vanish, so
   cards go back to the page colour and the tint becomes the backdrop. */
.zs-section-tone-soft { --zs-color-surface: var(--zs-color-background); }

.zs-section-tone-dark {
  --zs-band-bg: var(--zs-tone-dark);
  --zs-color-text: var(--zs-tone-on-dark);
  --zs-color-secondary: var(--zs-tone-on-dark);
  --zs-color-muted: color-mix(in srgb, var(--zs-tone-on-dark) 60%, transparent);
  --zs-color-surface: color-mix(in srgb, #fff 8%, transparent);
  --zs-color-background: color-mix(in srgb, #fff 6%, transparent);
  --zs-color-primary: var(--zs-tone-accent-on-dark);
}
.zs-section-tone-brand {
  --zs-band-bg: var(--zs-tone-brand);
  --zs-color-text: #fff;
  --zs-color-secondary: #fff;
  --zs-color-muted: color-mix(in srgb, #fff 72%, transparent);
  --zs-color-surface: color-mix(in srgb, #fff 12%, transparent);
  --zs-color-background: color-mix(in srgb, #fff 10%, transparent);
  /* On the brand band the accent IS the background, so it can only be white. */
  --zs-color-primary: #fff;
}
/* A solid button in the band's own colour is invisible against it. */
.zs-section-tone-brand .zs-btn {
  background: #fff;
  color: var(--zs-tone-brand);
}
.zs-section-tone-dark .zs-btn,
.zs-section-tone-brand .zs-btn { box-shadow: none; }
.zs-section-tone-dark :is(.zs-card, .zs-service, .zs-testimonial, .zs-plan, .zs-accordion-item),
.zs-section-tone-brand :is(.zs-card, .zs-service, .zs-testimonial, .zs-plan, .zs-accordion-item) {
  border-color: color-mix(in srgb, #fff 18%, transparent);
  box-shadow: none;
}

/* The page's own top padding would show as a light strip above a band that
   opens the page — a hero especially. Pull it off when that's the shape. */
main:has(.zs-content > .zs-section-band:first-child),
main:has(.zs-content > *:first-child .zs-hero-bg) { padding-top: 0; }
/* Consecutive bands of the same tone should read as one, not as a seam. */
.zs-section-band + .zs-section-band { margin-top: 0; }

/* A photo hero paints its own band and sets its own height, so the section's
   padding only shows up as a strip of flat colour above and below it. */
.zs-section-band:has(> .zs-section-inner > .zs-hero-bg:only-child) {
  padding-block: 0;
}

/* Columns collapse before the text gets too narrow to read, same as .zs-cards.
   The author picks the count; the collapse isn't theirs to break. */
.zs-section-cols > .zs-section-inner {
  display: grid;
  grid-template-columns: repeat(var(--zs-section-cols, 2), minmax(0, 1fr));
  align-items: start;
}
.zs-section-cols-2 { --zs-section-cols: 2; }
.zs-section-cols-3 { --zs-section-cols: 3; }
.zs-section-cols-4 { --zs-section-cols: 4; }

.zs-section-v-top > .zs-section-inner { justify-content: flex-start; }
.zs-section-v-center > .zs-section-inner { justify-content: center; }
.zs-section-v-bottom > .zs-section-inner { justify-content: flex-end; }
/* A min-height only means something if the inner box fills the section. */
.zs-section-v-center,
.zs-section-v-bottom { display: flex; flex-direction: column; }
.zs-section-v-center > .zs-section-inner,
.zs-section-v-bottom > .zs-section-inner { flex: 1; }

@media (max-width: 900px) {
  .zs-section-cols-3 { --zs-section-cols: 2; }
  .zs-section-cols-4 { --zs-section-cols: 2; }
}
@media (max-width: 640px) {
  .zs-section-cols > .zs-section-inner { --zs-section-cols: 1; }
}

/* Present for assistive tech and crawlers, absent from the visual layout —
   the standard clip-rect recipe. Used by the "show title" page setting. */
.zs-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ══════════ Content blocks ══════════
   Structure only: grids, rhythm, and the CSS that makes the interactive ones
   work without JS. Colour and character come from the theme layer. */

/* Shared section head + column counts. Every grid below collapses on the same
   two breakpoints, so a page reflows as one piece rather than block by block. */
.zs-blockhead { margin: 0 0 2.5rem; }
.zs-blockhead h2 {
  margin: 0 0 .35em;
  font-size: clamp(1.6rem, 1.15rem + 1.7vw, 2.35rem);
  letter-spacing: -0.015em;
}
.zs-blockhead-sub {
  margin: 0;
  color: var(--zs-color-muted);
  max-width: 44rem;
  font-size: 1.05rem;
}
/* The eyebrow is a label, not a sentence: small, spaced out, and paired with a
   short rule so it reads as a section marker rather than a lost line of text. */
.zs-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .6em;
  margin: 0 0 .7em;
  font-size: .78rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--zs-color-primary);
  font-weight: 700;
}
.zs-eyebrow::before {
  content: "";
  width: 1.8em;
  height: 2px;
  background: currentColor;
  opacity: .6;
}

/* ---------- Icons ----------
   One badge for every icon in the system: a tinted disc holding a monoline
   glyph. Emoji left over from older documents land in the same badge, so a page
   part-way through being updated doesn't look half-broken. */
.zs-icon-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 999px;
  margin-bottom: 1rem;
  background: color-mix(in srgb, var(--zs-color-primary) 12%, transparent);
  color: var(--zs-color-primary);
  flex: none;
}
.zs-icon { width: 1.6rem; height: 1.6rem; display: block; }
.zs-icon-text { font-size: 1.5rem; line-height: 1; width: auto; height: auto; }
/* On a dark or brand band the tint has nothing to sit on, so the disc borrows
   the band's own light instead of the accent. */
.zs-section-tone-dark .zs-icon-badge,
.zs-section-tone-brand .zs-icon-badge {
  background: color-mix(in srgb, #fff 14%, transparent);
  color: var(--zs-color-text);
}

.zs-cols-1 { --zs-cols: 1; }
.zs-cols-2 { --zs-cols: 2; }
.zs-cols-3 { --zs-cols: 3; }
.zs-cols-4 { --zs-cols: 4; }
.zs-cols-5 { --zs-cols: 5; }
.zs-cols-6 { --zs-cols: 6; }

.zs-stats-grid, .zs-steps-list, .zs-team-grid, .zs-testimonial-grid,
.zs-services-grid, .zs-pricing-grid, .zs-gallery-grid, .zs-contactinfo-grid,
.zs-feature-items {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(var(--zs-cols, 3), minmax(0, 1fr));
}
@media (max-width: 900px) {
  .zs-stats-grid, .zs-steps-list, .zs-team-grid, .zs-testimonial-grid,
  .zs-services-grid, .zs-pricing-grid, .zs-gallery-grid, .zs-contactinfo-grid {
    --zs-cols: 2;
  }
}
@media (max-width: 640px) {
  .zs-stats-grid, .zs-steps-list, .zs-team-grid, .zs-testimonial-grid,
  .zs-services-grid, .zs-pricing-grid, .zs-gallery-grid, .zs-contactinfo-grid,
  .zs-feature-items {
    --zs-cols: 1;
  }
}

.zs-stats, .zs-steps, .zs-team, .zs-testimonials, .zs-logos, .zs-services,
.zs-pricing, .zs-gallery, .zs-accordion, .zs-contactinfo, .zs-timeline,
.zs-tabs, .zs-featurelist { margin: 3em 0; }

/* ---------- Stats ---------- */
.zs-stat { text-align: center; }
.zs-stat-value {
  margin: 0;
  font-family: var(--zs-font-heading);
  font-size: clamp(2rem, 1.4rem + 2vw, 3rem);
  font-weight: 700;
  line-height: 1.1;
  color: var(--zs-color-primary);
}
.zs-stat-suffix { font-size: .7em; }
.zs-stat-label { margin: .35em 0 0; color: var(--zs-color-muted); }

/* ---------- Steps ---------- */
.zs-steps-list { list-style: none; padding: 0; margin: 0; counter-reset: none; }
.zs-step { position: relative; padding-top: .5rem; }
.zs-step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 999px;
  background: var(--zs-color-primary);
  color: #fff;
  font-weight: 700;
  margin-bottom: .75rem;
}
/* With an icon present the position number becomes a chip on its corner —
   two discs in a row read as two separate things, which they aren't. */
.zs-step:has(.zs-step-icon) .zs-step-num {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  width: 1.6rem;
  height: 1.6rem;
  font-size: .78rem;
  box-shadow: 0 0 0 3px var(--zs-color-background);
}
.zs-step:has(.zs-step-icon) .zs-step-icon { margin-left: .4rem; margin-top: .4rem; }

.zs-step h3 { margin: 0 0 .4em; font-size: 1.2rem; }
.zs-step p { margin: 0; color: var(--zs-color-muted); font-size: 1rem; }

/* ---------- Team ---------- */
.zs-team-card { text-align: center; }
.zs-team-photo { margin-bottom: .85rem; }
.zs-team-photo img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: var(--zs-radius);
  display: block;
}
.zs-team-card h3 { margin: 0 0 .2em; font-size: 1.05rem; }
.zs-team-role { margin: 0; color: var(--zs-color-muted); font-size: .9rem; }
.zs-team-link { display: inline-block; margin-top: .5rem; font-size: .85rem; }

/* ---------- Testimonials ---------- */
.zs-testimonial {
  margin: 0;
  padding: 1.5rem;
  background: var(--zs-color-surface);
  border-radius: var(--zs-radius);
}
.zs-testimonial blockquote {
  margin: 0 0 1rem;
  padding: 0;
  border: 0;
  background: none;
  font-size: 1.02rem;
}
.zs-testimonial figcaption { display: flex; align-items: center; gap: .75rem; }
.zs-testimonial-avatar img {
  width: 44px; height: 44px; border-radius: 999px; object-fit: cover; display: block;
}
.zs-testimonial-role { display: block; color: var(--zs-color-muted); font-size: .85rem; }
.zs-rating { margin: 0 0 .5rem; color: var(--zs-color-accent); letter-spacing: .1em; }

/* A slider is a scroll-snap strip: swipeable and keyboard-scrollable with no
   JS. The runtime script only adds auto-advance on top of this. */
.zs-slider {
  display: flex;
  gap: 1.5rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  padding-bottom: .5rem;
}
.zs-slider > * {
  flex: 0 0 min(100%, 26rem);
  scroll-snap-align: start;
}
.zs-slider::-webkit-scrollbar { height: 6px; }
.zs-slider::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--zs-color-muted) 40%, transparent);
  border-radius: 999px;
}

/* ---------- Logos ---------- */
.zs-logos-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 2.5rem;
}
.zs-logo img { max-height: 44px; width: auto; display: block; }

/* ---------- Services ---------- */
.zs-service {
  display: block;
  padding: 1.5rem;
  background: var(--zs-color-surface);
  border-radius: var(--zs-radius);
  text-decoration: none;
  color: inherit;
}
.zs-service-link:hover { background: color-mix(in srgb, var(--zs-color-primary) 8%, var(--zs-color-surface)); }
.zs-service-media { margin: -1.5rem -1.5rem 1rem; }
.zs-service-media img {
  width: 100%; aspect-ratio: 16/10; object-fit: cover; display: block;
  border-radius: var(--zs-radius) var(--zs-radius) 0 0;
}
.zs-service h3 { margin: 0 0 .45em; font-size: 1.25rem; letter-spacing: -.01em; }
.zs-service p { margin: 0; color: var(--zs-color-muted); font-size: 1rem; }

/* ---------- Pricing ---------- */
.zs-plan {
  padding: 1.75rem;
  background: var(--zs-color-surface);
  border-radius: var(--zs-radius);
  border: 1px solid transparent;
  display: flex;
  flex-direction: column;
  gap: .75rem;
}
.zs-plan-featured { border-color: var(--zs-color-primary); }
.zs-plan h3 { margin: 0; font-size: 1.05rem; }
.zs-plan-price {
  margin: 0;
  font-family: var(--zs-font-heading);
  font-size: 2rem;
  font-weight: 700;
  line-height: 1.1;
}
.zs-plan-period { font-size: .9rem; font-weight: 400; color: var(--zs-color-muted); }
.zs-plan-features { list-style: none; padding: 0; margin: 0; flex: 1; }
.zs-plan-features li { padding-left: 1.4em; position: relative; margin-bottom: .4em; }
.zs-plan-features li::before {
  content: "✓";
  position: absolute;
  left: 0;
  color: var(--zs-color-primary);
}
.zs-plan .zs-btn { align-self: flex-start; }

/* ---------- Gallery ---------- */
.zs-gallery-item { margin: 0; }
.zs-gallery-item img {
  width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block;
  border-radius: var(--zs-radius);
}
.zs-gallery-item figcaption {
  margin-top: .4rem; font-size: .85rem; color: var(--zs-color-muted);
}

/* ---------- Accordion ---------- */
.zs-accordion-list { display: grid; gap: .6rem; }
.zs-accordion-item {
  background: var(--zs-color-surface);
  border-radius: var(--zs-radius);
  padding: .9rem 1.1rem;
}
.zs-accordion-item summary {
  cursor: pointer;
  font-weight: 600;
  list-style: none;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
}
.zs-accordion-item summary::-webkit-details-marker { display: none; }
.zs-accordion-item summary::after { content: "+"; color: var(--zs-color-primary); }
.zs-accordion-item[open] summary::after { content: "−"; }
.zs-accordion-answer { padding-top: .7rem; color: var(--zs-color-muted); }

/* ---------- Contact info ---------- */
.zs-contact-item { text-align: center; }
.zs-contact-icon { margin-inline: auto; margin-bottom: .75rem; }
.zs-contact-label {
  margin: 0 0 .2em; font-weight: 600; font-size: .95rem;
}
.zs-contact-value { margin: 0; color: var(--zs-color-muted); }
.zs-contact-value a { text-decoration: none; }

/* ---------- Timeline ---------- */
.zs-timeline-list { list-style: none; padding: 0; margin: 0; }
.zs-timeline-item {
  display: grid;
  grid-template-columns: 7rem 1fr;
  gap: 1.5rem;
  padding: 0 0 1.75rem 0;
  position: relative;
}
/* The rail is drawn on the item, not a pseudo-element on the list, so the last
   entry can stop it rather than leaving a line hanging into whitespace. */
.zs-timeline-item::before {
  content: "";
  position: absolute;
  left: calc(7rem - .75rem);
  top: .6rem;
  bottom: -.6rem;
  width: 2px;
  background: color-mix(in srgb, var(--zs-color-muted) 25%, transparent);
}
.zs-timeline-item:last-child::before { display: none; }
.zs-timeline-year {
  margin: 0;
  font-weight: 700;
  color: var(--zs-color-primary);
  font-family: var(--zs-font-heading);
}
.zs-timeline-body h3 { margin: 0 0 .3em; font-size: 1.05rem; }
.zs-timeline-body p { margin: 0; color: var(--zs-color-muted); }
@media (max-width: 640px) {
  .zs-timeline-item { grid-template-columns: 1fr; gap: .4rem; }
  .zs-timeline-item::before { display: none; }
}

/* ---------- Tabs (radio-driven, no JS) ---------- */
.zs-tabs-wrap { display: flex; flex-wrap: wrap; }
.zs-tab-input { position: absolute; opacity: 0; pointer-events: none; }
.zs-tab-label {
  order: -1;
  cursor: pointer;
  padding: .6rem 1.1rem;
  border-bottom: 2px solid transparent;
  color: var(--zs-color-muted);
  font-weight: 600;
}
.zs-tab-panel { display: none; width: 100%; padding-top: 1.25rem; }
.zs-tab-input:checked + .zs-tab-label {
  color: var(--zs-color-primary);
  border-bottom-color: var(--zs-color-primary);
}
.zs-tab-input:checked + .zs-tab-label + .zs-tab-panel { display: block; }
/* Keyboard users must see which tab has focus — the label is the only visible
   control, since the input itself is off-screen. */
.zs-tab-input:focus-visible + .zs-tab-label {
  outline: 2px solid var(--zs-color-primary);
  outline-offset: 2px;
}
.zs-tab-media img { width: 100%; border-radius: var(--zs-radius); display: block; margin-bottom: 1rem; }

/* ---------- Feature list ---------- */
.zs-feature-items { list-style: none; padding: 0; margin: 0; gap: .6rem 2rem; }
.zs-feature-items li { padding-left: 1.6em; position: relative; }
.zs-feature-items li::before {
  content: "✓";
  position: absolute;
  left: 0;
  color: var(--zs-color-primary);
  font-weight: 700;
}

/* ---------- Buttons ---------- */
.zs-buttons { display: flex; flex-wrap: wrap; gap: .75rem; margin: 1.5em 0; }
.zs-buttons-center { justify-content: center; }
.zs-buttons-right { justify-content: flex-end; }
.zs-btn-outline {
  background: transparent;
  border: 2px solid currentColor;
  color: var(--zs-color-primary);
}

/* ---------- Marquee ---------- */
.zs-marquee {
  overflow: hidden;
  margin: 3em 0;
  padding: .9rem 0;
  background: var(--zs-color-secondary);
  color: #fff;
}
.zs-marquee-track { display: flex; width: max-content; animation: zs-marquee 26s linear infinite; }
.zs-marquee-run { display: flex; }
.zs-marquee-word {
  padding: 0 2rem;
  font-family: var(--zs-font-heading);
  font-weight: 600;
  white-space: nowrap;
}
.zs-marquee-word::after { content: "•"; margin-left: 2rem; opacity: .45; }
@keyframes zs-marquee {
  from { transform: translateX(0); }
  /* Exactly one run's width, so the second copy lands where the first started. */
  to { transform: translateX(-50%); }
}
/* Motion that never stops is a genuine accessibility problem, so respect the
   system setting rather than animating regardless. */
@media (prefers-reduced-motion: reduce) {
  .zs-marquee-track { animation: none; }
  .zs-slider { scroll-behavior: auto; }
}

/* ---------- Page header ---------- */
.zs-pageheader {
  padding: 3.5rem 1.25rem;
  background: var(--zs-color-surface);
  background-size: cover;
  background-position: center;
  border-radius: var(--zs-radius);
  margin: 0 0 2.5em;
}
.zs-pageheader-image { position: relative; color: #fff; }
/* The scrim is a pseudo-element so the author's background image stays a single
   background declaration and the text keeps its contrast over any photo. */
.zs-pageheader-image::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgb(0 0 0 / .45);
  border-radius: inherit;
}
.zs-pageheader-inner { position: relative; }
.zs-pageheader-image .zs-pageheader-title { color: #fff; }
.zs-pageheader-title { margin: 0; font-size: clamp(1.6rem, 1.2rem + 1.6vw, 2.4rem); }
.zs-pageheader-sub { margin: .5em 0 0; opacity: .9; }
/* A logo with no file yet — keeps the row from collapsing while a site is
   still being filled in. */
.zs-logo-name {
  font-family: var(--zs-font-heading);
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--zs-color-muted);
  letter-spacing: .01em;
}

/* ══════════ Header variants ══════════
   Seven arrangements of the same four pieces — logo, menu, contact, CTA. Each
   is a modifier on .zs-header rather than its own block, so the mobile nav,
   the sticky behaviour and the edge treatment are written once and every
   variant inherits them. Below 720px they all collapse to logo + burger. */

/* Doubled class on purpose. A theme is concatenated after this file and styles
   .zs-header directly — logistics gives it a 3px accent border — so a
   single-class rule here loses on source order and the author's "no edge"
   choice silently does nothing. */
.zs-header.zs-header-sticky { position: sticky; top: 0; z-index: 40; }
.zs-header.zs-header-edge-none { border-bottom: 0; box-shadow: none; }
.zs-header.zs-header-edge-shadow {
  border-bottom: 0;
  box-shadow: 0 1px 3px rgb(15 23 42 / .06), 0 8px 24px -16px rgb(15 23 42 / .2);
}
.zs-header-cta { margin-left: .75rem; padding: .5rem 1.1rem; font-size: .95rem; }

/* The strip above the header: contact details on the left, social on the right. */
.zs-topbar {
  background: var(--zs-tone-dark);
  color: var(--zs-tone-on-dark);
  font-size: .85rem;
}
.zs-topbar-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 2.5rem;
  flex-wrap: wrap;
}
.zs-topbar a { color: inherit; text-decoration: none; }
.zs-topbar-contact { display: flex; gap: 1.25rem; flex-wrap: wrap; }
.zs-headbar-item { display: inline-flex; align-items: center; gap: .4em; }
.zs-headbar-item .zs-icon { width: 1em; height: 1em; }

.zs-social { display: inline-flex; align-items: center; gap: .6rem; }
.zs-social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.9rem;
  height: 1.9rem;
  border-radius: 999px;
  text-decoration: none;
  color: inherit;
  background: color-mix(in srgb, currentColor 12%, transparent);
}
.zs-social-link:hover { background: color-mix(in srgb, currentColor 22%, transparent); }
.zs-social-link .zs-icon { width: 1rem; height: 1rem; }

/* Logo centred with the menu split around it. The two halves are separate
   <nav>s on desktop and a single one on mobile — splitting a list in half is a
   visual arrangement, so the mobile view gets the whole menu back in order. */
.zs-header-v-centered .zs-header-inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
}
.zs-header-v-centered .zs-nav-half:first-of-type .zs-nav-list { justify-content: flex-end; }
.zs-header-v-centered .zs-nav-mobile { display: none; }

/* Two rows, both centred. */
.zs-header-v-stacked .zs-header-inner {
  flex-direction: column;
  gap: .5rem;
  padding-block: 1rem;
}

/* Transparent over the hero until scrolled. The page must not reserve space
   for it, hence the negative margin pulling the content up underneath. */
/* Light type on a dark surface, without being a band.
   Repeats the dark band's palette flip rather than reusing
   .zs-section-tone-dark, because a theme hangs decoration off that class —
   logistics draws a 3px accent rule along the top of every dark band, which on
   a header or a hero reads as a stray line across the page. */
.zs-on-dark {
  --zs-color-text: var(--zs-tone-on-dark);
  --zs-color-secondary: var(--zs-tone-on-dark);
  --zs-color-muted: color-mix(in srgb, var(--zs-tone-on-dark) 60%, transparent);
  --zs-color-primary: var(--zs-tone-accent-on-dark);
  color: var(--zs-color-text);
}
.zs-header.zs-header-overlay {
  background: transparent;
  border-bottom: 0;
  box-shadow: none;
  transition: background .2s, box-shadow .2s;
}
body:has(.zs-header-overlay) main { margin-top: calc(-1 * var(--zs-header-h, 4rem)); }
body:has(.zs-header-overlay) main > .zs-container > .zs-article-page > .zs-content > :first-child {
  padding-top: var(--zs-header-h, 4rem);
}
.zs-header.zs-header-overlay.zs-header-solid {
  background: var(--zs-color-background);
  box-shadow: 0 1px 3px rgb(15 23 42 / .08);
  /* Solid means back on the page's own palette, not the dark-band one. */
  --zs-color-text: var(--zs-color-secondary);
  --zs-color-secondary: var(--zs-color-secondary);
}

/* Logo left, menu centre, contact + CTA right. */
.zs-header-v-contact .zs-header-inner { gap: 1.5rem; }
.zs-header-v-contact .zs-nav { margin-inline: auto; }
.zs-header-contact {
  display: flex;
  gap: 1.25rem;
  font-size: .85rem;
  color: var(--zs-color-muted);
}
.zs-header-contact a { color: inherit; text-decoration: none; }
@media (max-width: 1080px) { .zs-header-contact { display: none; } }

/* Menu always behind the burger, at every width. */
.zs-header-v-minimal .zs-nav-burger { display: block; }
.zs-header-v-minimal .zs-nav {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  min-width: 14rem;
  background: var(--zs-color-background);
  box-shadow: 0 12px 32px -12px rgb(15 23 42 / .3);
  padding: 1rem 1.25rem;
  z-index: 50;
}
.zs-header-v-minimal .zs-nav-toggle:checked ~ .zs-nav { display: block; }
.zs-header-v-minimal .zs-nav-list { flex-direction: column; gap: .75rem; }

@media (max-width: 720px) {
  .zs-topbar-inner { justify-content: center; }
  .zs-header-v-centered .zs-header-inner { display: flex; }
  .zs-header-v-centered .zs-nav-half { display: none; }
  .zs-header-v-centered .zs-nav-mobile { display: none; }
  .zs-header-v-centered .zs-nav-toggle:checked ~ .zs-nav-mobile { display: block; }
  .zs-header-v-stacked .zs-header-inner { flex-direction: row; }
  .zs-header-cta { display: none; }
}

/* ══════════ Footer variants ══════════ */

.zs-footer-v-minimal .zs-footer-inner { text-align: center; }
.zs-footer-grid {
  display: grid;
  grid-template-columns: 1.5fr repeat(auto-fit, minmax(9rem, 1fr));
  gap: 2.5rem;
  align-items: start;
}
.zs-footer-brand { display: grid; gap: .75rem; justify-items: start; }
.zs-footer-about { margin: 0; color: var(--zs-color-muted); max-width: 32rem; }
.zs-footer-col h3 { margin: 0 0 .8em; font-size: 1rem; }
.zs-footer-col .zs-nav-list { flex-direction: column; gap: .55rem; align-items: flex-start; }
.zs-footer-contact { list-style: none; margin: 0; padding: 0; display: grid; gap: .6rem; }
.zs-footer-contact li { display: flex; gap: .6em; align-items: start; color: var(--zs-color-muted); }
.zs-footer-contact a { color: inherit; text-decoration: none; }
.zs-footer-contact .zs-icon { width: 1.1em; height: 1.1em; flex: none; margin-top: .2em; }
.zs-copyright { margin: 2rem 0 0; color: var(--zs-color-muted); font-size: .9rem; }
.zs-footer-v-minimal .zs-copyright { margin: 0; }

/* The CTA band overlaps the footer's top edge, which is what makes it read as
   a card sitting on the seam rather than another stripe. */
.zs-footer-cta { padding-top: 2rem; }
.zs-footer-cta-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  background: var(--zs-tone-brand);
  color: #fff;
  border-radius: calc(var(--zs-radius) * 1.5);
  padding: 2.5rem 2.5rem;
  margin-bottom: -3rem;
  position: relative;
  z-index: 1;
}
.zs-footer-cta-inner h2 { margin: 0 0 .3em; color: #fff; }
.zs-footer-cta-inner p { margin: 0; color: rgb(255 255 255 / .8); }
.zs-footer-cta-inner .zs-btn { background: #fff; color: var(--zs-tone-brand); }
.zs-footer-v-cta { padding-top: 5rem; }

@media (max-width: 900px) {
  .zs-footer-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 640px) {
  .zs-footer-grid { grid-template-columns: 1fr; gap: 1.75rem; }
  .zs-footer-cta-inner { padding: 1.75rem; }
}

/* Theme: เข้ม จัดเต็ม (logistics)
 *
 * Modelled on the denser reference template: an agency look built from square
 * edges, an accent bar leading every section heading, tighter rhythm, and
 * uppercase micro-labels. Where `cargo` is soft and airy, this is deliberate
 * and structural.
 *
 * Personality only — base.css still owns every block's structure. */

h1, h2, h3, h4 { letter-spacing: -0.01em; }
h2 { font-size: clamp(1.6rem, 1.25rem + 1.3vw, 2.1rem); }

/* Denser than base: this style packs more onto a screen on purpose. */
.zs-stats, .zs-steps, .zs-team, .zs-testimonials, .zs-logos, .zs-services,
.zs-pricing, .zs-gallery, .zs-accordion, .zs-contactinfo, .zs-timeline,
.zs-tabs, .zs-featurelist { margin: 3.5em 0; }

/* The signature: an accent bar leading each section heading. */
.zs-blockhead h2, .zs-section-title {
  position: relative;
  padding-left: .85rem;
}
.zs-blockhead h2::before, .zs-section-title::before {
  content: "";
  position: absolute;
  left: 0;
  top: .18em;
  bottom: .18em;
  width: 4px;
  background: var(--zs-color-primary);
}
/* The base centres the cards heading; the bar only reads correctly left-aligned. */
.zs-section-title { text-align: left; }
.zs-eyebrow { letter-spacing: .14em; font-size: .72rem; }

/* Header: solid, with a strong bottom rule. */
.zs-header {
  border-bottom: 3px solid var(--zs-color-primary);
}
.zs-header-inner { min-height: 4.25rem; }
.zs-nav-list a { font-weight: 600; text-transform: uppercase; font-size: .82rem; letter-spacing: .04em; }

/* Square corners throughout — the clearest break from the base look. */
.zs-card, .zs-service, .zs-testimonial, .zs-plan, .zs-accordion-item,
.zs-gallery-item img, .zs-team-photo img, .zs-figure img, .zs-btn {
  border-radius: 2px;
}
.zs-service-media img { border-radius: 2px 2px 0 0; }

.zs-card, .zs-service, .zs-testimonial, .zs-plan {
  border: 1px solid color-mix(in srgb, var(--zs-color-muted) 22%, transparent);
  background: var(--zs-color-background);
}
/* A left edge that fills in on hover, echoing the heading bars. */
.zs-service-link {
  border-left: 3px solid transparent;
  transition: border-color .15s, background .15s;
}
.zs-service-link:hover {
  border-left-color: var(--zs-color-primary);
  background: var(--zs-color-surface);
}

.zs-btn {
  padding: .8rem 1.5rem;
  font-weight: 700;
  text-transform: uppercase;
  font-size: .82rem;
  letter-spacing: .04em;
}

/* Stats as a solid band, which is how the reference presents its counters. */
.zs-stats {
  background: var(--zs-color-secondary);
  color: #fff;
  padding: 2.5rem 1.75rem;
}
.zs-stats .zs-blockhead h2 { color: #fff; }
.zs-stat-value { color: #fff; }
.zs-stat-label { color: rgb(255 255 255 / .72); text-transform: uppercase; font-size: .78rem; letter-spacing: .08em; }

/* Steps as squared plates rather than discs. */
.zs-step-num { border-radius: 2px; }
.zs-step { border-top: 3px solid color-mix(in srgb, var(--zs-color-primary) 30%, transparent); padding-top: 1.1rem; }

.zs-team-photo img { aspect-ratio: 3/4; }
.zs-team-card { text-align: left; }

.zs-timeline-year { font-size: 1.25rem; }
.zs-ctaband { border-radius: 2px; }
.zs-marquee { background: var(--zs-color-primary); }
.zs-footer { border-top: 3px solid var(--zs-color-primary); }

/* ══════════ Bands ══════════
   Where cargo's dark is a soft gradient, this one is near-black and flat, cut
   by a hard accent rule at the top edge — the same structural device as the
   heading bars, at page scale. */
:root {
  --zs-tone-soft: color-mix(in srgb, var(--zs-color-surface) 85%, var(--zs-color-secondary));
  --zs-tone-dark: color-mix(in srgb, var(--zs-color-secondary) 88%, #000);
  --zs-tone-brand: var(--zs-color-primary);
}
.zs-section-band { padding-block: clamp(3rem, 1.5rem + 4.5vw, 5.5rem); }
.zs-section-tone-dark, .zs-section-tone-brand { border-top: 3px solid var(--zs-color-primary); }
.zs-section-tone-brand { border-top-color: color-mix(in srgb, #000 35%, var(--zs-color-primary)); }

/* The heading bar has to survive the band it lands in. */
.zs-section-tone-dark .zs-blockhead h2::before,
.zs-section-tone-brand .zs-blockhead h2::before { background: currentColor; }

/* Cards go square-edged and hairline on dark too, not translucent. */
.zs-section-tone-dark :is(.zs-card, .zs-service, .zs-testimonial, .zs-plan) {
  background: color-mix(in srgb, #fff 5%, transparent);
}

/* The stats band styles itself; inside a toned section that would be a band
   inside a band. */
.zs-section-band .zs-stats { background: none; padding: 0; }
.zs-section-band .zs-stat-value, .zs-section-band .zs-stats .zs-blockhead h2 { color: inherit; }
.zs-section-band .zs-stat-label { color: var(--zs-color-muted); }

/* Icon badges follow the square language rather than the base's disc. */
.zs-icon-badge { border-radius: 2px; width: 3rem; height: 3rem; }
.zs-service .zs-icon-badge, .zs-step .zs-icon-badge { margin-bottom: .85rem; }
