/* astralab.com — storefront styles.
 *
 * Hand-written rather than a framework: this is a handful of pages that will
 * be pasted into WordPress templates, and a build step there means a build
 * step every time someone edits a headline.
 *
 * Everything is driven by the custom properties below, so recolouring the
 * whole site — or matching a WordPress theme later — is one block. */

:root {
  --brand: #12a06d;
  --brand-dark: #0d7e57;
  --brand-tint: #eefbf4;
  --ink: #161a26;
  --ink-2: #4c5468;
  --ink-3: #8b93a7;
  --line: #e4e7ee;
  --surface: #ffffff;
  --surface-2: #f7f8fa;
  --radius: 14px;
  --max: 1120px;
  /* One gutter, widened once at the bottom of this file for phones. Anything
     that has to clear the edge of the screen reads it from here rather than
     picking its own number. */
  --gutter: 20px;
  --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans Bengali", sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --brand: #2ec98a;
    --brand-dark: #3ddc97;
    --brand-tint: #0c2b20;
    --ink: #eef0f4;
    --ink-2: #b9c0d4;
    --ink-3: #8b93a7;
    --line: #232838;
    --surface: #0f1320;
    --surface-2: #0a0d16;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font);
  color: var(--ink);
  background: var(--surface);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { line-height: 1.2; letter-spacing: -0.02em; margin: 0; }
h1 { font-size: clamp(2rem, 5vw, 3.25rem); font-weight: 700; }
h2 { font-size: clamp(1.5rem, 3.2vw, 2.1rem); font-weight: 650; }
h3 { font-size: 1.0625rem; font-weight: 600; }
p { margin: 0; }
a { color: inherit; }

/* The gutter is the one thing on this page that must never be overridden by
   accident, so it is set on its own axis. .hero carries both classes and used
   to say `padding: 84px 0 64px` — same specificity, later in the file, so the
   shorthand quietly reset the sides to zero and the heading ran into the edge
   of any screen narrower than --max. Every block-direction padding below is
   written as padding-block for that reason. */
.wrap { max-width: var(--max); margin-inline: auto; padding-inline: var(--gutter); }
.section { padding-block: 72px; }

/* The two page shapes that are a .wrap in their own right rather than one
   nested inside a section. Both used to carry their padding as an inline
   style, which is how the services heading ended up flush against the edge of
   a phone: `padding: 64px 0 8px` beats every stylesheet rule there is, and the
   0 took the gutter with it. */
.page-head { padding-block: 64px 8px; text-align: center; }
.prose-page { max-width: 820px; padding-block: 56px 72px; }
.section--tint { background: var(--surface-2); }
.center { text-align: center; }
.lede { color: var(--ink-2); font-size: 1.0625rem; max-width: 58ch; }
.center .lede { margin-inline: auto; }
.eyebrow {
  font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--brand);
}
.stack > * + * { margin-top: 14px; }

/* ---- header ---- */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.site-header .wrap {
  display: flex; align-items: center; gap: 20px; height: 68px;
}
.logo { display: flex; align-items: center; gap: 10px; font-weight: 650; text-decoration: none; }
.logo-mark {
  width: 32px; height: 32px; border-radius: 9px; display: grid; place-items: center;
  background: var(--brand); color: #fff; font-weight: 700; font-size: 0.9rem;
}
.logo-sub { display: block; font-size: 0.6875rem; font-weight: 400; color: var(--ink-3); }
.nav { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.nav a {
  padding: 8px 12px; border-radius: 8px; text-decoration: none;
  color: var(--ink-2); font-size: 0.9375rem;
}
.nav a:hover { background: var(--surface-2); color: var(--ink); }
.nav-toggle { display: none; }

@media (max-width: 820px) {
  .nav {
    position: absolute; inset: 68px 0 auto; flex-direction: column; align-items: stretch;
    background: var(--surface); border-bottom: 1px solid var(--line);
    padding: 10px var(--gutter) 16px;
    gap: 2px;
  }
  /* Collapsed by default; the checkbox hack keeps this scriptless, so the menu
     still opens if the JS that fetches the catalogue fails to load. */
  .nav[hidden] { display: none; }
  .nav-toggle {
    display: grid; place-items: center; margin-left: auto;
    width: 40px; height: 40px; border: 1px solid var(--line);
    border-radius: 10px; background: var(--surface); cursor: pointer;
  }
  .nav .btn { margin-top: 8px; }
}

/* ---- buttons ---- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 20px; border-radius: 10px; font-weight: 600; font-size: 0.9375rem;
  text-decoration: none; border: 1px solid transparent; cursor: pointer;
  transition: background .15s, border-color .15s;
}
.btn--primary { background: var(--brand); color: #fff; }
.btn--primary:hover { background: var(--brand-dark); }
.btn--ghost { border-color: var(--line); color: var(--ink); background: var(--surface); }
.btn--ghost:hover { background: var(--surface-2); }
.btn--lg { padding: 14px 26px; font-size: 1rem; }

/* ---- hero ---- */
/* Block only. This element also carries .wrap, and a shorthand here takes the
   side gutter away with it. */
.hero { padding-block: 84px 64px; }
.hero-grid { display: grid; gap: 44px; align-items: center; }
@media (min-width: 900px) { .hero-grid { grid-template-columns: 1.05fr 0.95fr; } }
.hero h1 { margin-top: 14px; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 26px; }
.hero-note { margin-top: 16px; font-size: 0.875rem; color: var(--ink-3); }

.badges { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 26px; }
.badge {
  font-size: 0.8125rem; padding: 6px 12px; border-radius: 999px;
  background: var(--brand-tint); color: var(--brand-dark); font-weight: 550;
}
@media (prefers-color-scheme: dark) { .badge { color: var(--brand); } }

/* Terminal-style panel — shows the install being a few commands rather than
   a project, which is the whole pitch. */
.terminal {
  background: #0d1018; border: 1px solid #232838; border-radius: var(--radius);
  overflow: hidden; box-shadow: 0 20px 50px -30px rgba(0,0,0,.55);
}
.terminal-bar { display: flex; gap: 6px; padding: 12px 14px; border-bottom: 1px solid #232838; }
.dot { width: 10px; height: 10px; border-radius: 50%; background: #333a4d; }
.terminal pre {
  margin: 0; padding: 18px; overflow-x: auto;
  font: 0.8125rem/1.75 ui-monospace, SFMono-Regular, Menlo, monospace; color: #c9d2e3;
}
.terminal .c { color: #6b768e; }
.terminal .g { color: #3ddc97; }

/* ---- cards / grids ---- */
.grid { display: grid; gap: 18px; }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 22px;
}
.card h3 { margin-bottom: 6px; }
.card p { color: var(--ink-2); font-size: 0.9375rem; }
.card-icon {
  width: 38px; height: 38px; border-radius: 10px; display: grid; place-items: center;
  background: var(--brand-tint); color: var(--brand-dark); margin-bottom: 14px;
}
@media (prefers-color-scheme: dark) { .card-icon { color: var(--brand); } }

/* ---- steps ---- */
.steps { counter-reset: step; }
.step { display: flex; gap: 16px; }
.step-num {
  flex: none; width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center;
  background: var(--brand); color: #fff; font-weight: 650; font-size: 0.875rem;
}

/* ---- product cards, filled from the hub API ----
   Two products stretched across 1120px left each card 530px wide and almost
   empty. The grid is capped so cards stay a readable width and the section
   reads as a considered shelf rather than a gap. */
#product-grid { max-width: 880px; margin-inline: auto; gap: 20px; }

.product {
  display: flex; flex-direction: column; gap: 14px;
  border: 1px solid var(--line); border-radius: 16px; padding: 26px;
  background: var(--surface); transition: border-color .15s, transform .15s, box-shadow .15s;
}
.product:hover {
  border-color: var(--brand);
  transform: translateY(-2px);
  box-shadow: 0 18px 40px -28px rgba(0,0,0,.45);
}
/* An unreleased product should read as quieter than a purchasable one without
   looking broken or disabled. */
.product--soon { background: var(--surface-2); }
.product--soon:hover { border-color: var(--line); transform: none; box-shadow: none; }

.product-head { display: flex; align-items: center; gap: 14px; }
.product-mark {
  flex: none; width: 46px; height: 46px; border-radius: 12px; display: grid; place-items: center;
  background: var(--brand); color: #fff; font-size: 1.25rem; font-weight: 700;
}
.product--soon .product-mark { background: var(--ink-3); }
.product-title { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.product-title h3 { margin: 0; }

.product-status {
  align-self: start; font-size: 0.6875rem; padding: 3px 9px; border-radius: 999px;
  font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
  background: var(--brand-tint); color: var(--brand-dark);
}
.product-status--soon { background: #fdf3e2; color: #8a5a08; }
@media (prefers-color-scheme: dark) {
  .product-status { color: var(--brand); }
  .product-status--soon { background: #33260c; color: #f0b34a; }
}

.product-summary { color: var(--ink-2); font-size: 0.9375rem; }

.product-meta { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.product-meta li {
  font-size: 0.75rem; padding: 4px 10px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--ink-3);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

.product-latest {
  font-size: 0.8125rem; color: var(--ink-2);
  border-left: 2px solid var(--brand); padding-left: 12px;
}
.product-latest strong { color: var(--ink); font-weight: 600; }

/* Pushed to the bottom so both cards' buttons align even when one has a
   release note and the other does not. */
.product-cta { margin-top: auto; }
.skeleton {
  border-radius: 8px; background: var(--surface-2); color: transparent;
  animation: pulse 1.4s ease-in-out infinite;
}
@keyframes pulse { 50% { opacity: .55; } }

/* ---- pricing ---- */
.price-card { border: 2px solid var(--brand); border-radius: 18px; padding: 32px; text-align: center; }
.price { font-size: 3rem; font-weight: 700; letter-spacing: -0.03em; }
.price small { font-size: 1rem; font-weight: 400; color: var(--ink-3); }
.tick-list { list-style: none; padding: 0; margin: 22px 0 0; text-align: left; display: grid; gap: 10px; }
.tick-list li { display: flex; gap: 10px; font-size: 0.9375rem; color: var(--ink-2); }
.tick { color: var(--brand); flex: none; }

/* ---- faq ---- */
.faq { border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); padding: 18px 0; }
.faq summary { cursor: pointer; font-weight: 600; list-style: none; display: flex; justify-content: space-between; gap: 16px; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; color: var(--ink-3); font-weight: 400; }
.faq details[open] summary::after { content: "−"; }
.faq p { margin-top: 10px; color: var(--ink-2); font-size: 0.9375rem; max-width: 70ch; }

/* ---- cta / footer ---- */
.cta { background: var(--brand); color: #fff; border-radius: 18px; padding: 48px 32px; text-align: center; }
.cta h2, .cta p { color: #fff; }
.cta .btn--ghost { background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.3); color: #fff; }
.cta .btn--ghost:hover { background: rgba(255,255,255,.2); }

.site-footer { border-top: 1px solid var(--line); padding-block: 44px; color: var(--ink-3); font-size: 0.875rem; }
.footer-grid { display: grid; gap: 28px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.footer-grid h4 { font-size: 0.8125rem; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-2); margin: 0 0 12px; }
.footer-grid ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.footer-grid a { text-decoration: none; }
.footer-grid a:hover { color: var(--brand); }
.footer-bottom { margin-top: 32px; padding-top: 20px; border-top: 1px solid var(--line); display: flex; flex-wrap: wrap; gap: 12px; justify-content: space-between; }

.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;
}

/* ---- add-ons ---- */
.addon { display: flex; flex-direction: column; }
.addon--featured { border-color: var(--brand); }
.addon-head { display: flex; align-items: start; justify-content: space-between; gap: 16px; margin-bottom: 10px; }
.addon-head h3 { margin: 0; }
.addon-price { text-align: right; flex: none; }
.addon-amount { display: block; font-size: 1.375rem; font-weight: 700; letter-spacing: -0.02em; }
.addon-bundle { display: block; font-size: 0.75rem; color: var(--brand); font-weight: 600; }
.addon-note { margin-top: auto; padding-top: 12px; font-size: 0.8125rem; color: var(--ink-3); }

/* ---- billing period switch ---- */
.billing {
  display: flex; gap: 4px; padding: 4px; margin: 0 auto; width: fit-content; max-width: 100%;
  background: var(--surface); border: 1px solid var(--line); border-radius: 999px; flex-wrap: wrap;
  justify-content: center;
}
.billing-opt {
  border: 0; background: transparent; cursor: pointer; font: inherit; font-size: 0.875rem;
  font-weight: 550; color: var(--ink-2); padding: 9px 18px; border-radius: 999px;
  display: inline-flex; align-items: center; gap: 7px;
}
.billing-opt:hover { color: var(--ink); }
.billing-opt.is-active { background: var(--brand); color: #fff; }
.save {
  font-size: 0.6875rem; font-weight: 700; padding: 2px 7px; border-radius: 999px;
  background: var(--brand-tint); color: var(--brand-dark);
}
.billing-opt.is-active .save { background: rgba(255,255,255,.22); color: #fff; }
@media (prefers-color-scheme: dark) { .save { color: var(--brand); } }

/* ---- plans ---- */
.plan { display: flex; flex-direction: column; position: relative; }
.plan--popular { border-color: var(--brand); border-width: 2px; }
.plan-tag {
  position: absolute; top: -11px; left: 22px; font-size: 0.6875rem; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; background: var(--brand); color: #fff;
  padding: 4px 10px; border-radius: 999px;
}
.plan-for { color: var(--ink-3); font-size: 0.875rem; margin-top: 4px; min-height: 2.6em; }
.plan-price { margin-top: 14px; }
.plan-amount { font-size: 2.125rem; font-weight: 700; letter-spacing: -0.03em; }
.plan-period { color: var(--ink-3); font-size: 0.9375rem; }
/* Reserves its line even when empty, so switching billing period does not
   shunt the feature lists up and down. */
.plan-equiv { font-size: 0.8125rem; color: var(--brand); font-weight: 600; min-height: 1.4em; }
.plan .tick-list { margin-top: 16px; }
.plan .btn { margin-top: auto; width: 100%; }

/* ---- comparison table ----
   Wide enough for four columns only on a real screen. Below 760px it stops
   being a table: each feature becomes a block listing all three plans. A
   horizontally scrolling table hides exactly the columns someone is trying to
   compare, and gives no hint they exist. */
.compare {
  width: 100%; border-collapse: collapse; font-size: 0.9375rem;
  border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden;
}
.compare th, .compare td { padding: 13px 16px; text-align: left; border-bottom: 1px solid var(--line); }
.compare thead th { font-size: 0.75rem; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-3); font-weight: 600; }
.compare td:not(:first-child), .compare th:not(:first-child) { text-align: center; }
.compare tbody tr:last-child td { border-bottom: 0; }
.compare td:first-child { color: var(--ink-2); }

@media (max-width: 760px) {
  .compare, .compare tbody, .compare tr, .compare td { display: block; width: 100%; }
  /* The header row is redundant once every value names its own plan. */
  .compare thead { display: none; }

  .compare tr { padding: 14px 16px; border-bottom: 1px solid var(--line); }
  .compare tr:last-child { border-bottom: 0; }

  .compare td { padding: 0; border: 0; text-align: left; }
  .compare td:first-child {
    font-weight: 600; color: var(--ink); margin-bottom: 8px;
  }
  .compare td:not(:first-child) {
    display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
    padding: 5px 0; text-align: right; color: var(--ink);
  }
  .compare td:not(:first-child)::before {
    content: attr(data-label);
    color: var(--ink-3); font-size: 0.8125rem; text-align: left;
  }
}

/* ---- UX corrections ---- */

/* Anchor targets sit under the sticky header without this: clicking "Pricing"
   scrolls the section to y=0, which is 68px behind the bar. */
[id] { scroll-margin-top: 88px; }

html { scroll-behavior: smooth; }

/* Visible keyboard focus. The browser default is removed by nothing here, but
   it is nearly invisible against the brand green, so state it explicitly. */
:where(a, button, summary, input, select, textarea):focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 6px;
}

/* Touch targets. 40px is the practical floor for a thumb; the nav links and
   FAQ summaries were comfortably smaller than that on a phone. */
@media (max-width: 820px) {
  .nav a { padding: 12px; }
  .faq summary { padding: 4px 0; }
}

/* Respect a reduced-motion preference — the loading pulse and smooth scroll
   are exactly the kind of movement that setting exists to stop. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .skeleton { animation: none; }
  * { transition-duration: 0.01ms !important; }
}

/* The plan strapline reserves two lines to keep the three cards' prices on the
   same baseline. Stacked on mobile there is nothing to align with, and the gap
   just looks like a mistake. */
@media (max-width: 760px) {
  .plan-for { min-height: 0; }
}

/* ---- narrow screens ----
 *
 * Every rule in this file that changes with the width of the screen lives
 * here, in one block, in order of width. It was scattered before — some in the
 * middle of the file, some as inline styles on the HTML — which is how the
 * same mistake got made three times: a `padding` shorthand written for a wide
 * screen quietly setting the side gutter to zero.
 *
 * The rules to keep it from happening again:
 *   - the gutter is --gutter, and nothing else names a side padding on a .wrap
 *   - anything that also carries .wrap sets padding-block, never padding
 *   - vertical rhythm shrinks with the screen; the gutter narrows but stays
 */

/* Tablets. The nav collapses into the checkbox menu at 820 (see the header
   section), so this is really "no longer a desk". */
@media (max-width: 820px) {
  .hero { padding-block: 64px 52px; }
  .section { padding-block: 60px; }
  .page-head { padding-block: 48px 4px; }
  .prose-page { padding-block: 44px 56px; }
}

/* Phones. 32px of padding either side of a 360px screen leaves the words in a
   column, so the coloured blocks come in too. */
@media (max-width: 560px) {
  :root { --gutter: 16px; }

  .hero { padding-block: 48px 40px; }
  .section { padding-block: 48px; }
  .page-head { padding-block: 36px 4px; }
  .prose-page { padding-block: 36px 48px; }

  .cta { padding: 36px 22px; }
  .price-card { padding: 26px 20px; }
  .product { padding: 22px 18px; }
  .card { padding: 18px; }

  /* A row of pill buttons that cannot fit side by side should stack full
     width rather than leave one stranded and half the row empty. */
  .hero-actions .btn { flex: 1 1 100%; justify-content: center; }
}
