/* ═══════════════════════════════════════════════════════════════════════════
   COMPANY / TRANSACTIONAL PAGES — page-group rules
   2026 design system — Geomage Website (www.geomage.com)

   Loaded ALONGSIDE main.css by:
     /contact/ + /about-us/        frontend/contact_us.html
     /privacy-policy/              frontend/privacy-policy.html
     (nginx error_page 404)        frontend/404.html
     /download-software/           frontend/download.html
     /pricing-plan-g-space/        frontend/pricing_g-space.html  (+ pricing.css)

   Only what the design-system components do NOT already provide lives here:

     · .hero margin-top reset — none of these pages carries a .subnav, so the
       component's 116px header+subnav offset comes back to 70px (60px ≤720px),
       the same override pages/{home,services,tech,support,content}.css write.
     · .ccard*      — the contact-method cards: a loaded .diff card with a
                      call-to-action button pinned to its foot.
     · .co-prose    — two plain paragraphs inside a .panel (components/specs
                      .panel has no prose rhythm of its own).
     · .pol*        — the privacy-policy clauses, two-up.
     · .e404*       — the 404 fun-fact note and the section link grid.
     · .dl*         — the download page's product rows and their button rows.
     · .gsp*        — the g-Space pricing page: the common-features panel, the
                      selectable module cards, the [?] screenshot tooltips and
                      the running total. .price__* / .tooltip* class names in
                      that block are a JS contract (pricing-calculator.js binds
                      .price__item / .price__summ / .price__link--space) and are
                      restyled here rather than renamed.

   Everything else on these pages is a component: .hero (+ .hero__inner--narrow),
   .eyebrow / .section-head, .diff / .diff__grid, .split / .panel / .spec,
   .pkgs / .pkg, .btn variants, .cta, and the header/footer includes.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── HERO OFFSET (no subnav on these pages) ──────────────────────────────── */
.hero { margin-top: 70px; }
/* Anchor targets clear the fixed header only (header-2026.css assumes +subnav). */
section[id],
article[id] { scroll-margin-top: 86px; }
@media (max-width: 720px) {
  .hero { margin-top: 60px; }
  section[id],
  article[id] { scroll-margin-top: 76px; }
}

/* ═══ CONTACT ════════════════════════════════════════════════════════════ */

/* A .diff card that ends in a button: the card becomes a column so the
   call-to-action lines up across all three however long the copy runs. */
.ccard {
  display: flex;
  flex-direction: column;
}
/* One of the three is a <button> (Zendesk) and two are links, so the box is
   declared explicitly — a bare .btn inherits the body line-height on an <a>
   and the UA's `normal` on a <button>, which puts the three 3px apart. */
.ccard__cta.btn-outline {
  margin-top: auto;
  align-self: flex-start;
  padding: 11px 18px;
  font-size: 12.5px;
  line-height: 1.25;
  text-align: center;
}

/* Plain prose inside a .panel (support information). */
.co-prose p { font-size: 14px; line-height: 1.8; color: var(--text); }
.co-prose p + p { margin-top: 16px; }

/* ═══ PRIVACY POLICY ═════════════════════════════════════════════════════ */

.pol__grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
.pol { padding: 26px 26px 28px; transition: border-color .25s var(--ease), box-shadow .25s var(--ease); }
.pol:hover { border-color: var(--orange); box-shadow: var(--shadow-md); }
.pol__t {
  font-family: var(--font-head); font-size: 18px; font-weight: 700;
  color: var(--text-dark); line-height: 1.25; margin-bottom: 10px;
}
.pol__d { font-size: 14px; line-height: 1.8; color: var(--text); }
.pol__d a { color: var(--orange); font-weight: 600; text-decoration: none; word-break: break-word; }
.pol__d a:hover { text-decoration: underline; }
/* The seventh clause has no partner on its row. */
.pol--wide { grid-column: 1 / -1; }

/* ═══ 404 ════════════════════════════════════════════════════════════════ */

/* Fun-fact note, on the hero's dark ground. */
.e404__fact {
  display: flex; align-items: flex-start; gap: 13px;
  max-width: 560px; margin-top: 8px; padding: 16px 18px;
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: var(--radius-md);
}
.e404__fact svg {
  width: 20px; height: 20px; flex-shrink: 0; margin-top: 2px;
  stroke: #ff9240; fill: none; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
}
.e404__fact p { font-size: 13.5px; line-height: 1.65; color: rgba(255, 255, 255, .78); }
.e404__fact strong { color: #fff; font-weight: 700; }

/* Section links */
.e404__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.e404__link {
  display: flex; align-items: center; gap: 10px;
  padding: 16px 18px;
  font-size: 14px; font-weight: 600; color: var(--text-dark); text-decoration: none;
  background: var(--bg-white); border: 1px solid var(--border);
  border-radius: var(--radius-md);
  transition: all .22s var(--ease);
}
.e404__link:hover {
  border-color: var(--orange); color: var(--orange);
  box-shadow: var(--shadow-md); transform: translateY(-2px);
}
.e404__link svg {
  width: 17px; height: 17px; flex-shrink: 0;
  stroke: var(--orange); fill: none; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
.e404__link--primary { background: var(--orange); border-color: var(--orange); color: #fff; }
.e404__link--primary svg { stroke: #fff; }
.e404__link--primary:hover { background: var(--orange-hover); border-color: var(--orange-hover); color: #fff; }
.e404__link--primary:hover svg { stroke: #fff; }

/* ═══ DOWNLOAD ═══════════════════════════════════════════════════════════ */

/* download-modals.css (imported by main.css for the download flow's own
   modals) gives every .button__orange 40px of vertical margin and
   `display: flex`. .btn re-declares the display later in the cascade but
   nothing re-declares the margins, so the download buttons take them back
   here — the same fix pages/pricing.css writes for .plan__cta. */
.btn.button__orange { margin: 0; }

/* Product rows: screenshot + copy, alternating sides. */
.dl-row { display: grid; grid-template-columns: 1fr 1.05fr; gap: 44px; align-items: center; }
.dl-row + .dl-row { margin-top: 68px; padding-top: 68px; border-top: 1px solid var(--border); }
.dl-row--reverse .dl-row__media { order: 2; }
.dl-row__media {
  background: #0d1117; border: 1px solid var(--border);
  border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-md);
}
.dl-row__media img { display: block; width: 100%; height: auto; }
.dl-row__t {
  font-family: var(--font-head); font-size: 23px; font-weight: 700;
  line-height: 1.22; color: var(--text-dark); margin-bottom: 12px;
}
.dl-row__d { font-size: 14.5px; line-height: 1.75; color: var(--text); margin-bottom: 18px; }
/* .mod__features is card-scoped (12.5px, pinned to a flex card's foot). */
.dl-row__list { margin-top: 0; margin-bottom: 26px; font-size: 13.5px; }
.dl-row__cta { display: flex; gap: 12px; flex-wrap: wrap; }

/* ═══ g-SPACE PRICING ════════════════════════════════════════════════════ */

/* The legacy heading is set in caps in the source and is kept verbatim, so it
   takes a smaller size than the 44px .section-title default. */
.gsp-common__title { font-size: clamp(22px, 2.4vw, 30px); line-height: 1.25; }

.gsp-common { padding: 30px 32px; }
.gsp-common__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 26px 40px; }
.gsp-sublabel {
  font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-dark); margin-bottom: 12px; line-height: 1.5;
}
/* .mod__features is card-scoped (12.5px, pinned to a flex card's foot). */
.gsp-list { margin-top: 0; font-size: 13px; }
/* It also makes every <li> a flex row, which turns the trailing "[?]" span
   into a flex item of its own and parks it at the end of the first line.
   These items carry inline markup, so they go back to normal text flow with
   the component's orange dot re-hung as an absolute marker. */
.gsp-list li { display: block; position: relative; padding-left: 15px; line-height: 1.5; }
.gsp-list li::before { position: absolute; left: 0; top: 7px; margin-top: 0; }

/* ── MODULE CARDS ────────────────────────────────────────────────────────── */
/* Five modules: three to a row, the last two centred under them — a 5-column
   .pkgs__grid leaves 214px per card, and the 4-up default leaves one alone. */
.gsp-grid { display: flex; flex-wrap: wrap; justify-content: center; gap: 18px; }
.gsp-grid > .gsp-card { flex: 1 1 320px; max-width: 362px; }
.gsp-card { cursor: pointer; }
/* The whole card toggles its checkbox (pricing-calculator.js), so the selected
   state belongs on the card. :has() is Chrome/Safari/Firefox 121+; where it is
   unsupported the checkbox alone shows the state and nothing breaks. */
.gsp-card:has(.price__item:checked) {
  border-color: var(--orange);
  box-shadow: 0 0 0 1px var(--orange-border);
}
.gsp-card .plan__price { font-size: 26px; }
.gsp-note { font-size: 12.5px; font-weight: 600; color: var(--blue); margin-bottom: 14px; }

/* "Add" control — the legacy blue button, now the card's foot. */
.gsp-add {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  margin-top: auto; padding: 13px 18px;
  font-size: 14px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: #fff; background: var(--blue); border-radius: var(--radius-sm);
  transition: background .2s var(--ease);
}
.gsp-card:hover .gsp-add { background: #01527f; }
/* The checkbox is a state indicator, not the control: pricing-calculator.js
   calls preventDefault() on every click inside the card, which cancels the
   checkbox's own activation — a click landing on the input would do nothing at
   all. pointer-events:none sends every pointer click to the card handler
   instead, so clicking the box, the word ADD or anywhere in the card toggles
   exactly once. (In the legacy markup the input sat inside a <label>, so a
   click there toggled twice and left the module unchanged.) */
.gsp-add input {
  width: 16px; height: 16px; margin: 0;
  accent-color: #fff; flex-shrink: 0; pointer-events: none;
}
.gsp-card:has(.price__item:checked) .gsp-add { background: var(--orange); }

/* ── [?] SCREENSHOT TOOLTIPS ─────────────────────────────────────────────── */
/* Hover on a pointer, and focus for the keyboard: the [?] is focusable and the
   panel opens on :focus-within. No JS, same images, same alt text. */
.gsp-tip { position: relative; }
.gsp-tip__q { color: var(--orange); font-weight: 700; cursor: help; }
.gsp-tip__q:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; border-radius: 3px; }
/* `display: none` rather than the legacy `visibility: hidden`, and measured:
   the 22 screenshots are 1.7MB and a hidden-but-laid-out lazy image is still
   fetched at load. Hidden this way the page pulls 5KB of images instead of
   314KB, and each screenshot is fetched (~45KB) the first time its tooltip is
   opened. The width/height attributes give the panel its aspect ratio before
   the file lands, so it does not resize under the pointer. */
.gsp-tip__box {
  display: none;
  position: absolute; bottom: calc(100% + 10px); left: 0;
  width: 280px; max-width: 78vw; padding: 6px; z-index: 40;
  background: #1b2531; border: 1px solid rgba(255, 255, 255, .14);
  border-radius: var(--radius-md); box-shadow: var(--shadow-lg);
  color: #fff; font-size: 12.5px; font-weight: 500; line-height: 1.5; text-align: center;
}
.gsp-tip__box img { display: block; width: 100%; height: auto; border-radius: var(--radius-sm); }
.gsp-tip__box--title { width: 190px; padding: 10px 12px; }
.gsp-tip:hover > .gsp-tip__box,
.gsp-tip:focus-within > .gsp-tip__box { display: block; }

/* ── RUNNING TOTAL ───────────────────────────────────────────────────────── */
.price__total {
  max-width: 362px; margin: 30px auto 0; padding: 16px 24px; text-align: center;
  font-family: var(--font-head); font-size: 20px; font-weight: 700;
  color: var(--text-dark);
  background: var(--bg-white); border: 1px solid var(--border);
  border-radius: var(--radius-md); box-shadow: var(--shadow-sm);
}
.price__summ { color: var(--orange); }
.price__total span + span { color: var(--orange); }

/* ── RESPONSIVE ──────────────────────────────────────────────────────────── */
@media (max-width: 980px) {
  .e404__grid { grid-template-columns: repeat(2, 1fr); }
  .dl-row { grid-template-columns: 1fr; gap: 28px; }
  .dl-row--reverse .dl-row__media { order: 0; }
  .dl-row + .dl-row { margin-top: 52px; padding-top: 52px; }
  .gsp-common__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 720px) {
  .pol__grid { grid-template-columns: 1fr; }
  .e404__fact { flex-direction: row; }
  .gsp-common { padding: 24px 20px; }
  .gsp-common__grid { grid-template-columns: 1fr; gap: 22px; }
  .gsp-grid > .gsp-card { max-width: none; }
  .gsp-tip__box { width: 240px; }
}
@media (max-width: 420px) {
  .e404__grid { grid-template-columns: 1fr; }
}
