/* Landing page stylesheet (gm-manager.com/home).
   Standalone on purpose: /home must never pull the app bundle or /static/style.css, so the
   colour tokens below are COPIED (values, not @import) from static/css/00-tokens.css. The app
   puts them on .light / .dark classes driven by a saved preference, and since the Light / Auto /
   Dark switch the landing page shares that preference (localStorage "gmv_theme"), so the same
   classes drive it here. The light tokens sit on :root and the dark ones on #app.dark, which is
   <body>: the inline bootstrap in home.html resolves "auto" to light or dark before first paint,
   so there is no prefers-color-scheme query left to fight with a forced light theme.
   Keep the values in sync with 00-tokens.css when the design changes. */

:root {
  --bg: #F6F5F2;
  --card: #fff;
  --cardb: rgba(0, 0, 0, .06);
  --cardb2: rgba(0, 0, 0, .10);
  --text: #1A1D21;
  --muted: #6B7280;
  --faint: #9CA3AF;
  --accent: #3B8C8C;
  --amber: #D4A017;
  --green: #2E7D5B;
  --blue: #4A90D9;
  --purple: #7C5CBF;
  --seg: #F1F1EE;
  --input: #F8F8F6;
  --sh: 0 4px 14px rgba(15, 20, 25, .05), 0 1px 2px rgba(15, 20, 25, .03);
  --shl: 0 22px 46px -22px rgba(20, 30, 40, .30), 0 4px 12px -8px rgba(20, 30, 40, .14);
  --cover: linear-gradient(135deg, #eef1ef, #e5eae8);
  --onaccent: #fff;
}

#app.dark {
  --bg: #111214;
  --card: #1C1E22;
  --cardb: rgba(255, 255, 255, .07);
  --cardb2: rgba(255, 255, 255, .13);
  --text: #E8E9EB;
  --muted: #9CA3AF;
  --faint: #6B7280;
  --accent: #4AADAD;
  --amber: #E4B429;
  --green: #3DA876;
  --blue: #5CA0E8;
  --purple: #9B7FD4;
  --seg: #2A2D32;
  --input: #22252A;
  --sh: 0 6px 18px rgba(0, 0, 0, .32), 0 1px 2px rgba(0, 0, 0, .24);
  --shl: 0 28px 56px -22px rgba(0, 0, 0, .66);
  --cover: linear-gradient(135deg, #24272c, #1a1d21);
  --onaccent: #10201f;
}

/* ── base ─────────────────────────────────────────────────────────────────── */

* { box-sizing: border-box }

html { -webkit-text-size-adjust: 100% }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: 'Inter', -apple-system, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  letter-spacing: -.1px;
  line-height: 1.6;
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block }

a { color: var(--accent); text-decoration: none }
a:hover { text-decoration: underline }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px }

.wrap { width: 100%; max-width: 1080px; margin: 0 auto; padding: 0 20px }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── typography ───────────────────────────────────────────────────────────── */

h1, h2, h3 { letter-spacing: -.6px; line-height: 1.2; margin: 0 0 12px }
h1 { font-size: 34px; font-weight: 800 }
h2 { font-size: 26px; font-weight: 700 }
h3 { font-size: 17px; font-weight: 600; letter-spacing: -.2px }
p { margin: 0 0 14px }

.lead { font-size: 17px; color: var(--muted); max-width: 60ch }
.eyebrow {
  font-size: 12px; font-weight: 700; letter-spacing: .8px; text-transform: uppercase;
  color: var(--accent); margin: 0 0 10px;
}

/* ── buttons ──────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 13px 22px; border-radius: 12px; font-size: 15px; font-weight: 600;
  border: 1px solid transparent; text-decoration: none; min-height: 46px;
}
.btn:hover { text-decoration: none }
.btn-primary { background: var(--accent); color: var(--onaccent); box-shadow: var(--sh) }
.btn-primary:hover { filter: brightness(1.06) }
.btn-ghost { background: var(--card); color: var(--text); border-color: var(--cardb2) }
.btn-ghost:hover { border-color: var(--accent) }

/* ── header ───────────────────────────────────────────────────────────────── */

.site-head {
  position: sticky; top: 0; z-index: 10;
  background: var(--bg);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid var(--cardb);
}
.site-head .wrap {
  display: flex; align-items: center; gap: 16px; min-height: 62px; flex-wrap: wrap;
  padding-top: 8px; padding-bottom: 8px;
}
.brand { display: flex; align-items: center; gap: 10px; color: var(--text); font-weight: 700 }
.brand:hover { text-decoration: none }
.brand img { width: 30px; height: 30px; border-radius: 8px }
.brand-sub { display: block; font-size: 11px; font-weight: 500; color: var(--muted) }
.head-nav { display: flex; align-items: center; gap: 18px; margin-left: auto; flex-wrap: wrap }
.head-nav a { color: var(--muted); font-size: 14px; font-weight: 500 }
.head-nav a:hover { color: var(--text) }
/* .head-nav a above is one specificity step higher than .btn-primary, so the button colour has
   to be restated here or the label renders in --muted on the accent pill. */
.head-nav .btn { padding: 8px 16px; min-height: 38px; font-size: 14px }
.head-nav a.btn-primary, .head-nav a.btn-primary:hover { color: var(--onaccent) }

/* Light / Auto / Dark switch. Same shape as the app's sidebar pill: one segmented control, the
   active segment carried by aria-pressed so the state is one attribute rather than a class the
   markup and the script could disagree about. It is the one nav item that stays on a phone (the
   anchors below stand down under 640px), so it has to read at 12px without wrapping. */
.theme-switch {
  display: flex; align-items: center; gap: 2px;
  background: var(--seg); border: 1px solid var(--cardb); border-radius: 999px; padding: 2px;
}
.theme-switch button {
  appearance: none; border: 0; background: none; cursor: pointer;
  color: var(--muted); font: inherit; font-size: 12px; font-weight: 600;
  padding: 5px 10px; border-radius: 999px; line-height: 1;
}
.theme-switch button:hover { color: var(--text) }
.theme-switch button[aria-pressed="true"] {
  background: var(--card); color: var(--text); box-shadow: var(--sh);
}
.theme-switch button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px }
.theme-switch .ts-ic { display: none; width: 15px; height: 15px }

/* The one screenshot that exists in both themes. Exactly one of the pair is in the flow, so the
   figure keeps its size and neither image can stack under the other. */
.shot-on-dark { display: none }
#app.dark .shot-on-light { display: none }
#app.dark .shot-on-dark { display: block }

/* ── sections ─────────────────────────────────────────────────────────────── */

section { padding: 54px 0 }
section > .wrap > h2 { margin-bottom: 6px }
.section-sub { color: var(--muted); margin-bottom: 26px; max-width: 62ch }
.alt { background: var(--seg) }

/* ── hero ─────────────────────────────────────────────────────────────────── */

.hero { padding: 44px 0 10px }
.hero h1 { max-width: 16ch }
.hero .lead { font-size: 18px }
.cta-row { display: flex; flex-wrap: wrap; gap: 12px; margin: 22px 0 10px }
.hero-note { font-size: 13px; color: var(--faint); margin: 0 }
.hero-shot { margin-top: 30px }
.hero-shot .frame { box-shadow: var(--shl) }

/* ── cards and grids ──────────────────────────────────────────────────────── */

.grid { display: grid; grid-template-columns: 1fr; gap: 14px }
.card {
  background: var(--card); border: 1px solid var(--cardb); border-radius: 14px;
  padding: 18px 18px 16px; box-shadow: var(--sh);
}
.card p { margin: 0; color: var(--muted); font-size: 14.5px }
.card h3 { margin-bottom: 6px }
/* A call to action inside a card. Two selectors deep on purpose: `.card p { margin: 0 }` above
   would otherwise win and the button would sit flush against the paragraph. */
.card .card-cta { margin-top: 14px }
.tag {
  display: inline-block; font-size: 11px; font-weight: 700; letter-spacing: .6px;
  text-transform: uppercase; color: var(--accent); margin-bottom: 8px;
}

/* ── screenshot gallery ───────────────────────────────────────────────────── */

.shots { display: grid; grid-template-columns: 1fr; gap: 22px; align-items: start }
.shot { margin: 0 }
.shot figcaption { color: var(--muted); font-size: 14px; margin-top: 10px }
.shot-phone figcaption { text-align: center }

/* ── device frames ────────────────────────────────────────────────────────── */

/* Every screenshot sits in a frame so a flat capture reads as a screen. Two of them, and both
   are pure CSS over the same markup: a wrapper div, the chrome, the untouched <img>. The corners
   clip the image here rather than on the image itself, which is what lets the phone bezel round
   at 40px while the capture inside it stays square.

   The frame is NOT what the lightbox opens: landing.js reads the <img> inside the figure, so the
   overlay still shows the raw file with no chrome around it. */
.frame {
  overflow: hidden;                       /* the rounded corners do the clipping, not the image */
  background: var(--cover);
  box-shadow: var(--sh);
}
/* `vertical-align` and not `display: block` on purpose: a `.frame img` display rule would
   out-specify `.shot-on-dark { display: none }` above and both themes' captures would stack. */
.frame img { width: 100%; height: auto; vertical-align: bottom }

/* A browser window: a bar with three traffic lights and an address pill, then the capture. The
   bar colour comes from the landing tokens, so it flips with the theme like everything else. */
.frame-browser {
  border: 1px solid var(--cardb2); border-radius: 12px;
}
.frame-bar {
  display: flex; align-items: center; gap: 6px;
  padding: 0 12px; height: 34px;
  background: var(--seg); border-bottom: 1px solid var(--cardb);
}
.frame-bar .dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--faint); flex: none;
}
.frame-bar .dot:nth-child(1) { background: #EC6A5E }
.frame-bar .dot:nth-child(2) { background: #F4BF4F }
.frame-bar .dot:nth-child(3) { background: #61C554 }
.frame-url {
  margin-left: 10px; flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  background: var(--card); border: 1px solid var(--cardb);
  border-radius: 999px; padding: 3px 12px;
  font-size: 11.5px; color: var(--muted); text-align: center;
}

/* A phone: a dark bezel in BOTH themes, because a real phone is dark whatever the page is, and a
   light bezel around a light screenshot would disappear. The island is the only ornament. */
.frame-phone {
  position: relative;
  max-width: 300px; margin-inline: auto;
  padding: 10px; border-radius: 44px;
  background: #17191C; border: 1px solid rgba(255, 255, 255, .10);
  box-shadow: var(--shl);
}
.frame-phone img { border-radius: 34px }
/* The island floats over the capture; the screenshot's own status bar area is empty, so nothing
   readable sits underneath it. */
.frame-island {
  position: absolute; top: 20px; left: 50%; transform: translateX(-50%);
  width: 84px; height: 22px; border-radius: 999px;
  background: #17191C; z-index: 1;
}

/* ── screenshot lightbox ──────────────────────────────────────────────────── */

/* A screenshot is a thumbnail here, so the frame says so: it lifts on hover and the cursor is
   zoom-in. landing.js gives every [data-zoom] figure role="button" and a tab stop, so the focus
   ring below is the keyboard's half of the same affordance. */
[data-zoom] { cursor: zoom-in; transition: transform .3s cubic-bezier(.2, .7, .3, 1) }
@media (hover: hover) and (pointer: fine) {
  [data-zoom]:hover { transform: scale(1.015) }
}
[data-zoom]:focus-visible { outline: 2px solid var(--accent); outline-offset: 6px }

/* The overlay fills the viewport and scrolls ITSELF once the image is zoomed, which is what makes
   a 1440px capture pannable on a phone. Both themes get the same dark scrim: the point is to take
   the page away, and a light scrim over a light screenshot shows nothing. */
.image-lightbox {
  position: fixed; inset: 0; z-index: 900;
  overflow: auto; overscroll-behavior: contain;
  background: rgba(12, 14, 16, .86);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  opacity: 0; transition: opacity .2s ease;
}
.image-lightbox[data-open="true"] { opacity: 1 }
.image-lightbox-inner {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; min-height: 100%; margin: 0; padding: 64px 16px 24px;
}
.image-lightbox img {
  max-width: min(100%, 1400px); max-height: 76vh; width: auto; height: auto;
  object-fit: contain; border-radius: 12px; box-shadow: 0 30px 70px rgba(0, 0, 0, .45);
  cursor: zoom-in; transform: scale(.96); transition: transform .2s ease;
}
.image-lightbox[data-open="true"] img { transform: scale(1) }
/* Second step: the file at its own size, panned by scrolling the overlay. */
.image-lightbox[data-zoomed="true"] img {
  max-width: none; max-height: none; cursor: zoom-out; border-radius: 0;
}
.image-lightbox figcaption {
  max-width: 46ch; text-align: center; font-size: 14px; line-height: 1.6;
  color: rgba(255, 255, 255, .86);
}
.image-lightbox-close {
  position: fixed; top: 12px; right: 12px;
  display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0;
  border-radius: 999px; border: 1px solid rgba(255, 255, 255, .25);
  background: rgba(255, 255, 255, .12); color: #fff; cursor: pointer;
  transition: background .2s ease;
}
.image-lightbox-close svg { width: 20px; height: 20px }
.image-lightbox-close:hover { background: rgba(255, 255, 255, .24) }
.image-lightbox-close:focus-visible { outline: 2px solid #fff; outline-offset: 2px }

@media (min-width: 640px) {
  .image-lightbox-inner { padding: 72px 32px 32px }
  .image-lightbox-close { top: 18px; right: 18px }
}

.steps { counter-reset: step; display: grid; grid-template-columns: 1fr; gap: 14px; margin: 0; padding: 0; list-style: none }
.steps li {
  background: var(--card); border: 1px solid var(--cardb); border-radius: 14px;
  padding: 18px; box-shadow: var(--sh);
}
.steps li::before {
  counter-increment: step; content: counter(step);
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--accent); color: var(--onaccent);
  font-weight: 700; font-size: 14px; margin-bottom: 10px;
}
.steps h3 { margin-bottom: 4px }
.steps p { margin: 0; color: var(--muted); font-size: 14.5px }

/* ── list with checks ─────────────────────────────────────────────────────── */

.ticks { list-style: none; margin: 0 0 18px; padding: 0 }
.ticks li { position: relative; padding-left: 26px; margin-bottom: 10px; color: var(--muted) }
.ticks li::before {
  content: ""; position: absolute; left: 4px; top: .62em;
  width: 8px; height: 8px; border-radius: 50%; background: var(--accent);
}
.ticks strong { color: var(--text); font-weight: 600 }

/* ── two column split ─────────────────────────────────────────────────────── */

.split { display: grid; grid-template-columns: 1fr; gap: 22px; align-items: start }

/* ── privacy panel ────────────────────────────────────────────────────────── */

.panel {
  background: var(--card); border: 1px solid var(--cardb); border-left: 3px solid var(--accent);
  border-radius: 14px; padding: 22px; box-shadow: var(--sh);
}

/* ── FAQ ──────────────────────────────────────────────────────────────────── */

.faq { display: grid; gap: 12px }
.faq-item {
  background: var(--card); border: 1px solid var(--cardb); border-radius: 14px;
  padding: 16px 18px; box-shadow: var(--sh);
}
.faq-item h3 { margin-bottom: 6px }
.faq-item p { margin: 0; color: var(--muted); font-size: 14.5px }

/* ── read more links ──────────────────────────────────────────────────────── */

.links { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px }
.links li { font-size: 15px }

/* ── footer ───────────────────────────────────────────────────────────────── */

.site-foot {
  border-top: 1px solid var(--cardb); padding: 30px 0 44px;
  color: var(--muted); font-size: 14px;
}
/* Nine links wrap into two or three rows on a phone, so the gap is a row gap as well as a column
   one and the list reads as a list rather than a blob. */
.foot-links { display: flex; flex-wrap: wrap; gap: 10px 16px; margin: 12px 0 14px; padding: 0; list-style: none }
.foot-note { font-size: 13px; color: var(--faint); margin: 0 }
.foot-brand { font-weight: 600; color: var(--text) }
.foot-company { margin: 0 0 4px; color: var(--muted); font-size: 13px; max-width: 70ch }
.foot-contact { margin: 0 0 12px; font-size: 13px; color: var(--muted) }
.foot-contact a { color: var(--accent) }

/* The card marks (Comgate, Visa, Mastercard). Each brandmark is the vendor's own file, byte for
   byte, and each one carries its isolation area INSIDE the viewBox: Visa's artwork fills 57% of
   the width and 30% of the height of its box, Mastercard's 76% and 67%, Comgate's the whole box.
   So a plain gap would leave three different-looking holes in one row. Two things fix that
   without touching a vendor file: the heights below are picked per mark so the part you can SEE
   comes out at a matching size, and the negative inline margins cancel each mark's own side
   padding, which leaves `gap` as the real, equal distance between the visible marks.

   The dark page gets the inverse files. Both are in the markup and the swap is this rule, so it
   costs no script and no second request: the hidden one is display:none and never loads. */
.foot-pay { margin: 0 0 14px }
.foot-pay-marks {
  display: flex; align-items: center; flex-wrap: wrap; gap: 18px;
  margin: 0; padding: 0; list-style: none;
}
.foot-pay-marks li { display: flex; align-items: center }
.foot-pay-marks a { display: flex; align-items: center }
/* max-width has to go: the base `img` rule caps every image at the width of its box, and the box
   here is an <li> that the negative margin below has already made narrower than the mark. */
.foot-pay-marks img { display: block; width: auto; max-width: none; flex: none }
/* One height per brand, sized so the part you can SEE ends up level, and the negative margin
   that cancels that brand's own padding. Both live on the <li>, never on the <img>: a negative
   margin on the image itself makes the browser resolve its auto width against the shrunken line
   rather than the file's own ratio, and the artwork comes out scaled down by exactly the padding
   the margin was there to remove. */
.pay-comgate img { height: 20px }
.pay-visa { margin-inline: -16.2px }
.pay-visa img { height: 46px }
.pay-mc { margin-inline: -5px }
.pay-mc img { height: 30px }
/* Scoped through .foot-pay-marks so these beat the `img` rule above, which is one tag more
   specific than a bare class on its own. */
.foot-pay-marks .pay-dark { display: none }
#app.dark .foot-pay-marks .pay-light { display: none }
#app.dark .foot-pay-marks .pay-dark { display: block }

/* On a phone the anchor row would wrap to a second line and eat a fifth of the screen in a
   sticky header. The sections it points at are all reachable by scrolling, and a hamburger would
   need JavaScript, which this page does not load - so the anchors simply stand down under 640px
   and the header keeps the brand and the one action that matters. */
@media (max-width: 639px) {
  .head-nav a:not(.btn) { display: none }
  /* The switch stays - it is a preference the visitor may want on a phone more than anywhere
     else - it just gets tighter so brand, switch and Log in still fit one row. */
  .theme-switch button { padding: 6px 7px; display: block }
  .theme-switch { gap: 0 }
  .theme-switch .ts-tx { display: none }
  .theme-switch .ts-ic { display: block }
  /* brand + switch + Log in have to fit ONE row at 375px, or the sticky header doubles in height
     and eats an eighth of the screen. Measured: 139 + 93 + 74 with these gaps, against 335. */
  .head-nav { gap: 10px }
  .site-head .wrap { gap: 10px }
}

/* ── wider viewports ──────────────────────────────────────────────────────── */

@media (min-width: 640px) {
  h1 { font-size: 46px }
  h2 { font-size: 30px }
  section { padding: 66px 0 }
  .hero { padding: 60px 0 14px }
  .grid { grid-template-columns: repeat(2, 1fr) }
  .steps { grid-template-columns: repeat(3, 1fr) }
}

@media (min-width: 900px) {
  h1 { font-size: 54px }
  .wrap { padding: 0 32px }
  .grid { grid-template-columns: repeat(3, 1fr) }
  .shots { grid-template-columns: repeat(2, 1fr) }
  .shot-wide { grid-column: 1 / -1 }
  .split { grid-template-columns: 1.1fr .9fr; gap: 40px }
  .hero .lead { font-size: 19px }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important }
  [data-zoom]:hover { transform: none }
}
