/* ==========================================================================
   Agastyx Labs — site styles

   NO BUILD STEP, DELIBERATELY. A marketing site that needs a toolchain
   installed before you can look at it is a marketing site nobody previews
   before it ships. Everything is here or in one small JS file: open a page
   from a filesystem and it works.

   The reasoning behind the layout, colour and type decisions is kept out of
   this file. It ships to every visitor, so it says what the CSS does and
   nothing about what runs it.
   ========================================================================== */

:root {
  /* Deep tech, not consumer SaaS: near-black ground, the brand crimson, one
     cool signal. Hues are fixed; only lightness moves between surfaces, so
     nothing ever looks like a different brand two sections down. */
  --ground:      #07090f;
  --surface:     #0d111a;
  --surface-2:   #131924;
  --rule:        #1f2735;
  --rule-strong: #2c3648;

  --ink:         #eef2f8;
  --soft:        #9aa7bd;
  /* #64718a was 4.05:1 on the ground - under the 4.5 small text needs, and
     every use of it IS small text: stat labels, field notes, the footer
     baseline. Lifted until it passes (5.47:1) while staying a clear step
     below --soft, so the three-level hierarchy survives. */
  --faint:       #7c8798;

  /* #a71e27 is the logo red, sampled from the mark. It is only 2.7:1 on the
     ground, so it can never carry text - it is the fill colour, with white
     on top. --accent is the same hue lifted until it clears 4.5:1, and that
     is what links, focus rings and small type use. */
  --brand:       #a71e27;   /* the mark's red: solid fills, primary buttons */
  --brand-hover: #c02330;
  --accent:      #ef4a57;   /* lifted crimson: links, focus, active, eyebrows */
  --accent-hover:#ff7a83;
  --accent-weak: rgba(239, 74, 87, 0.13);
  --signal:      #63e6c3;   /* cool green: confirmations, live things */
  --signal-weak: rgba(99, 230, 195, 0.12);

  /* Warm glass. A neutral grey tint reads pasted-on over a crimson-lit
     ground; these carry the brand hue at low saturation so a card looks lit
     by the same light as everything behind it. */
  --glass:        rgba(48, 16, 20, 0.42);
  --glass-strong: rgba(34, 11, 14, 0.62);
  --hair:         rgba(255, 255, 255, 0.14);
  --hair-soft:    rgba(255, 255, 255, 0.07);

  --measure: 68ch;          /* never let prose run wider than this */
  --gutter: clamp(1rem, 4vw, 2.5rem);
  --radius: 14px;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  /* Inter Tight carries the display voice, Inter the reading voice, and
     Instrument Serif italic appears on exactly one word per page. All three
     are self-hosted - see fonts.css. */
  --font-display: "Inter Tight", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font:         "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-italic:  "Instrument Serif", Georgia, "Times New Roman", serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

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

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--accent-hover); }

/* One visible focus ring everywhere. Removing it is how a keyboard user
   loses their place on a page they cannot see the pointer on. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

h1, h2, h3 { font-family: var(--font-display); line-height: 1.12; letter-spacing: -0.03em; margin: 0 0 0.5em; }
h1 { font-size: clamp(2.4rem, 6.4vw, 4.6rem); font-weight: 600; line-height: 0.95; }
h2 { font-size: clamp(1.7rem, 3.6vw, 2.6rem); font-weight: 600; }
h3 { font-size: 1.12rem; font-weight: 600; letter-spacing: -0.02em; }

/* THE ONE SERIF WORD. Exactly one word per page is set in Instrument Serif
   italic - the single typographic gesture on an otherwise all-sans site. It
   works because it is rare; used twice on a page it reads as a mistake. */
h1 em, h2 em, .display em {
  font-family: var(--font-italic); font-style: italic; font-weight: 400;
  letter-spacing: -0.005em;
}
p  { margin: 0 0 1.1em; max-width: var(--measure); }

.lede { font-size: clamp(1.05rem, 2.2vw, 1.3rem); color: var(--soft); }
.eyebrow {
  font-size: 0.78rem; font-weight: 640; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--accent); margin-bottom: 0.9rem;
}
.muted { color: var(--soft); }
.small { font-size: 0.9rem; }

/* ── Layout ─────────────────────────────────────────────────────────── */

.wrap { width: min(1180px, 100%); margin-inline: auto; padding-inline: var(--gutter); }
section { padding-block: clamp(3.5rem, 9vw, 7rem); }
.section-head { max-width: var(--measure); margin-bottom: clamp(2rem, 5vw, 3rem); }

.grid { display: grid; gap: clamp(1rem, 2.5vw, 1.75rem); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }

/* ── Header ─────────────────────────────────────────────────────────── */

.site-header {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--ground) 72%, transparent);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--hair-soft);
}
.site-header .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; min-height: 74px;
}
/* Logo left, nav capsule centred, one action right. With only two items the
   capsule drifts right and the bar reads as a list; the third item is what
   makes it a composition. */
@media (min-width: 941px) {
  .site-header .wrap { display: grid; grid-template-columns: 1fr auto 1fr; }
  .site-header .nav { justify-self: center; }
  .header-cta { justify-self: end; }
}
.header-cta {
  display: inline-flex; align-items: center;
  padding: 0.5rem 1.1rem; border-radius: 999px;
  background: #fff; color: #180600;
  font-size: 0.86rem; font-weight: 600; letter-spacing: -0.01em;
  text-decoration: none; white-space: nowrap;
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.35);
  transition: transform 0.35s var(--ease-out), background 0.35s var(--ease-out);
}
.header-cta:hover { transform: translateY(-1px); background: #fff2f3; color: #180600; }
@media (max-width: 520px) { .header-cta { display: none; } }
/* Below the grid breakpoint the bar is flex again, and source order would
   put the burger between the logo and the action. The burger belongs on the
   edge - it is the thumb's target. */
@media (max-width: 940px) {
  .header-cta { order: 2; }
  .nav-toggle { order: 3; }
}
.brand { display: flex; align-items: center; gap: 0.65rem; font-weight: 680;
         color: var(--ink); text-decoration: none; letter-spacing: -0.01em; }
.brand:hover { color: var(--ink); }
.brand img { height: 28px; width: auto; flex: none; }
.brand small { display: block; font-size: 0.62rem; font-weight: 500;
               letter-spacing: 0.14em; text-transform: uppercase; color: var(--faint); }

/* The nav is a capsule floating on the page rather than a bar ruled off from
   it: a hairline outline, each item carrying its own soft chip. */
.nav {
  display: flex; align-items: center; gap: 3px;
  padding: 5px; border: 1px solid var(--hair); border-radius: 12px;
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
}
.nav a {
  color: rgba(238, 242, 248, 0.78); text-decoration: none;
  font-size: 0.86rem; font-weight: 500; letter-spacing: -0.01em;
  padding: 0.46rem 0.8rem; border-radius: 8px;
  background: rgba(255, 255, 255, 0.04);
  transition: background-color 0.3s var(--ease-out), color 0.3s var(--ease-out);
}
.nav a:hover { color: var(--ink); background: rgba(255, 255, 255, 0.12); }
.nav a[aria-current="page"] { color: var(--ink); background: var(--accent-weak); }

.nav-toggle {
  display: none; background: none; border: 1px solid var(--rule-strong);
  color: var(--ink); border-radius: 8px; padding: 0.45rem 0.6rem; cursor: pointer;
}

@media (max-width: 940px) {
  .nav-toggle { display: block; }
  .nav {
    position: absolute; inset: 74px 12px auto 12px; flex-direction: column;
    align-items: stretch; gap: 2px; padding: 0.75rem;
    border-radius: 18px; border: 1px solid var(--hair);
    background: rgba(9, 11, 18, 0.95);
    backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  }
  .nav:not([data-open="true"]) { display: none; }
  .nav a { padding: 0.8rem 0.7rem; font-size: 1rem; background: none; }
}

/* ── Buttons ────────────────────────────────────────────────────────── */

/* Fully round. A pill reads as an action; a rounded rectangle reads as a
   field, and this page has both. */
.btn {
  display: inline-flex; align-items: center; gap: 0.6rem;
  padding: 0.72rem 1.4rem; border-radius: 999px; font-weight: 600;
  font-size: 0.96rem; letter-spacing: -0.01em; text-decoration: none;
  border: 1px solid transparent; cursor: pointer; white-space: nowrap;
  transition: transform 0.35s var(--ease-out), background 0.35s var(--ease-out),
              box-shadow 0.35s var(--ease-out), border-color 0.35s var(--ease-out);
}
.btn-primary {
  padding: 0.42rem 0.42rem 0.42rem 1.4rem;
  background: linear-gradient(96deg, var(--brand) 0%, #d8323d 100%);
  color: #fff; box-shadow: 0 14px 40px rgba(167, 30, 39, 0.38);
}
.btn-primary:hover {
  transform: translateY(-2px); color: #fff;
  box-shadow: 0 20px 52px rgba(167, 30, 39, 0.5);
}
/* The arrow sits in its own light tile on the end of the pill. Drawn as a
   data URI rather than an <svg> in every button, so the markup on eleven
   pages stays a plain <a> and the icon cannot drift between them. */
.btn-primary::after {
  content: ""; flex: none;
  width: 2.2em; height: 2.2em; border-radius: 999px;
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23200608' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 10h12M11 5l5 5-5 5'/%3E%3C/svg%3E") center / 1.05em no-repeat;
}
/* A submit button is an action, not a link onward - no arrow. */
button.btn-primary::after { display: none; }
button.btn-primary { padding: 0.72rem 1.4rem; }
.btn-ghost { border-color: var(--hair); color: var(--ink); background: rgba(255,255,255,0.04); }
.btn-ghost:hover { background: rgba(255,255,255,0.1); color: var(--ink); transform: translateY(-1px); }
.btn-row { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.75rem; }

/* ── Cards ──────────────────────────────────────────────────────────── */

.card {
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--radius); padding: clamp(1.25rem, 3vw, 1.75rem);
}
.card h3 { margin-bottom: 0.4rem; }
.card p:last-child { margin-bottom: 0; }
.card-link { text-decoration: none; color: inherit; display: block;
             transition: border-color 0.15s ease, background 0.15s ease; }
.card-link:hover { border-color: var(--rule-strong); background: var(--surface-2); color: inherit; }

.card-icon {
  width: 42px; height: 42px; border-radius: 10px; display: grid; place-items: center;
  background: var(--accent-weak); color: var(--accent); margin-bottom: 1rem;
}
.card-icon svg { width: 22px; height: 22px; }

/* ── Hero ───────────────────────────────────────────────────────────── */

.hero {
  position: relative; overflow: hidden; isolation: isolate;
  padding-block: clamp(4.5rem, 13vw, 9rem);
  background: linear-gradient(168deg, #140508 0%, var(--ground) 62%);
}
/* Two hairlines running the height of the hero. They do nothing except give
   the eye a vertical to measure the headline against, which is most of why
   the reference composition feels deliberate rather than centred-by-default. */
.hero::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: -1;
  background:
    linear-gradient(90deg, transparent calc(30% - 1px), var(--hair-soft) 30%, transparent calc(30% + 1px)),
    linear-gradient(90deg, transparent calc(70% - 1px), var(--hair-soft) 70%, transparent calc(70% + 1px));
}
@media (max-width: 860px) { .hero::after { display: none; } }
.hero::before {
  /* One soft light source, off-centre. A full-bleed gradient wash reads as a
     template; a single source reads as a photograph of something. */
  content: ""; position: absolute; inset: -30% -10% auto auto;
  width: 60rem; height: 42rem; pointer-events: none;
  background: radial-gradient(45% 45% at 60% 40%,
              rgba(239, 74, 87, 0.15), transparent 70%);
}
.hero .wrap { position: relative; }
.hero h1 { max-width: 15ch; text-shadow: 0 6px 40px rgba(0, 0, 0, 0.45); }
.hero .lede { max-width: 48ch; }

/* A hairline note above the headline, as on the reference: small, quiet, and
   ruled off so it reads as a caption to the page rather than a first line. */
.hero-note {
  display: flex; align-items: center; gap: 0.7rem;
  width: fit-content; max-width: 34ch; margin-bottom: 1.6rem;
  padding-top: 0.85rem; border-top: 1px solid var(--hair-soft);
  font-size: 0.78rem; line-height: 1.45; color: var(--faint);
}
.hero-note svg { width: 20px; height: 20px; flex: none; }

/* Stat cards are glass, not flat panels: they sit over the hero's own light
   rather than covering it. */
.stat-row {
  display: flex; flex-wrap: wrap; gap: 0.9rem;
  margin-top: clamp(2.25rem, 5vw, 3rem); padding: 0; list-style: none;
}
.stat {
  display: grid; align-content: space-between; gap: 1.5rem;
  width: 13rem; min-height: 8.25rem; padding: 1.1rem;
  border: 1px solid var(--hair); border-radius: 16px;
  background: var(--glass);
  backdrop-filter: blur(16px) saturate(1.1);
  -webkit-backdrop-filter: blur(16px) saturate(1.1);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09);
}
.stat:nth-child(2) { background: linear-gradient(150deg, rgba(120, 22, 30, 0.5), rgba(44, 12, 16, 0.5)); }
.stat b {
  display: block; font-family: var(--font-display);
  font-size: clamp(1.5rem, 2.4vw, 1.9rem); font-weight: 500;
  line-height: 1; letter-spacing: -0.03em;
}
.stat span { font-size: 0.8rem; color: var(--faint); }
@media (max-width: 560px) { .stat { flex: 1 1 9rem; width: auto; } }

/* ── Feature rows ───────────────────────────────────────────────────── */

.split { display: grid; gap: clamp(1.5rem, 5vw, 3.5rem); align-items: center;
         grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr)); }
.split-media {
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--radius); padding: clamp(1rem, 3vw, 2rem);
}

.ticks { list-style: none; padding: 0; margin: 1.25rem 0 0; }
.ticks li { position: relative; padding-left: 1.75rem; margin-bottom: 0.7rem; color: var(--soft); }
.ticks li::before {
  content: ""; position: absolute; left: 0; top: 0.55em;
  width: 9px; height: 9px; border-radius: 3px;
  background: var(--signal); box-shadow: 0 0 0 4px var(--signal-weak);
}

/* Numbered steps. The count is the content - a reader should be able to see
   "three things" before reading any of them - so the marker is drawn rather
   than left to the browser's small grey default. */
.steps { list-style: none; margin: 0; padding: 0; counter-reset: step; }
.steps li {
  counter-increment: step; position: relative; padding-left: 2.25rem;
  margin-bottom: 1rem; color: var(--soft); font-size: 0.94rem; line-height: 1.65;
}
.steps li:last-child { margin-bottom: 0; }
.steps li::before {
  content: counter(step);
  position: absolute; left: 0; top: 0.05rem;
  width: 1.5rem; height: 1.5rem; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--accent-weak); color: var(--accent);
  font-size: 0.78rem; font-weight: 680; font-variant-numeric: tabular-nums;
}
.steps li b { color: var(--ink); font-weight: 600; }

/* ── Callout / CTA ──────────────────────────────────────────────────── */

.callout {
  background: linear-gradient(160deg, var(--surface-2), var(--surface));
  border: 1px solid var(--rule-strong); border-radius: var(--radius);
  padding: clamp(1.75rem, 5vw, 3rem);
}
.callout h2 { margin-bottom: 0.4rem; }

/* ── Footer ─────────────────────────────────────────────────────────── */

.site-footer { border-top: 1px solid var(--rule); padding-block: 3rem 2.5rem; color: var(--soft); }
/* FOUR COLUMNS. With five, auto-fit wrapped the last one onto a row of its
   own and left a band of empty space above the footer band - which is what
   the gap was. Social links moved into Company, so Legal is back on the top
   row and the grid fills. */
.footer-grid { display: grid; gap: 2rem 2.5rem; align-items: start;
               grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr)); }
.site-footer h2 { font-size: 0.78rem; letter-spacing: 0.12em; text-transform: uppercase;
                  color: var(--faint); margin: 0 0 0.75rem; font-weight: 640; }
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: 0.45rem; }
.site-footer a { color: var(--soft); text-decoration: none; font-size: 0.94rem; }
.site-footer a:hover { color: var(--ink); }
/* SOCIAL: ICONS ONLY, IN A ROW, TOP RIGHT OF THE FOOTER, level with the
   column headings (owner, 3 Oct 2026; was beside the copyright). "The icon
   is enough to understand which social media it is" (2 Oct). Each link
   still carries its name as aria-label and title, so a screen reader and a
   hover both say it. A comfortable round hit area, because most visitors
   arrive on a phone. */
.social { display: flex; align-items: center; gap: 0.5rem; margin: 0; }
.social li { margin: 0; }
.social a { display: inline-flex; align-items: center; justify-content: center;
            width: 2.25rem; height: 2.25rem; border-radius: 999px;
            border: 1px solid var(--rule); color: var(--soft);
            transition: color 0.2s var(--ease-out), border-color 0.2s var(--ease-out); }
.social a:hover { color: var(--ink); border-color: var(--soft); }
.social a:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.social svg { width: 17px; height: 17px; flex: none; }
.footer-bottom { align-items: center; }
.footer-top { display: flex; align-items: flex-start; gap: 2rem 2.5rem; position: relative; }
.footer-top .footer-grid { flex: 1; min-width: 0; }
.footer-top .social { flex: none; }
@media (max-width: 700px) { .footer-top { flex-direction: column; } }
/* On a wide screen the icons sit in the empty space right of the footer's
   columns, centred both ways in it (owner, 3 Oct 2026). That space runs from
   the content edge to the window edge: the gutter plus half of what the
   window has beyond .wrap's 1180px. Below 1360px it is too narrow for the
   two icons, so they stay at the top right of the columns. */
@media (min-width: 1360px) {
  .footer-top .social { position: absolute; top: 50%;
                        left: calc(100% + (var(--gutter) + (100vw - 1180px) / 2) / 2);
                        transform: translate(-50%, -50%); }
}

/* WhatsApp: a button, not a line of text. It is the fastest way to reach a
   person from a phone, which is how most of this site's traffic arrives.

   THE GLYPH SITS IN ITS OWN TILE. Set loose beside a two-line label it read
   as a stray icon rather than the button's mark - too small against the text
   block, and with nothing to align its optical centre to. A round tile gives
   it a shape the same weight as the label, and the two then centre on each
   other instead of on the pill. */
.wa {
  display: inline-flex; align-items: center; gap: 0.8rem;
  margin: 0 0 1.5rem; padding: 0.6rem 1.3rem 0.6rem 0.6rem;
  border: 1px solid rgba(37, 211, 102, 0.3); border-radius: 999px;
  background: rgba(37, 211, 102, 0.08);
  color: var(--ink); text-decoration: none;
  transition: background 0.3s var(--ease-out), border-color 0.3s var(--ease-out),
              transform 0.3s var(--ease-out);
}
.wa:hover {
  background: rgba(37, 211, 102, 0.15); border-color: rgba(37, 211, 102, 0.55);
  color: var(--ink); transform: translateY(-1px);
}
.wa svg {
  width: 2.5rem; height: 2.5rem; flex: none; padding: 0.55rem;
  border-radius: 999px; background: #25d366; color: #07130a;
}
.wa-text { display: grid; gap: 0.1rem; line-height: 1.3; }
.wa-text { font-size: 0.94rem; font-weight: 600; letter-spacing: -0.01em; }
.wa small { font-size: 0.8rem; font-weight: 400; color: var(--soft); font-variant-numeric: tabular-nums; }
.footer-bottom { display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between;
                 margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid var(--rule);
                 font-size: 0.86rem; color: var(--faint); }

/* ── Footer band: watermark left, programmes right ──────────────────────
   The wordmark is set enormous at almost no opacity. It is texture, not a
   thing to read - at this weight it registers as the page having a floor,
   which is the job the reference gives it. */
.footer-band {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 1.5rem; margin-top: 2.5rem; padding-top: 2rem;
  border-top: 1px solid var(--hair-soft);
}
.footer-mark {
  font-family: var(--font-display); font-size: clamp(2.6rem, 8vw, 6rem);
  font-weight: 700; line-height: 0.8; letter-spacing: -0.05em;
  color: rgba(255, 255, 255, 0.05); user-select: none;
}
.programmes { text-align: right; }
.programmes-label {
  display: block; margin-bottom: 0.85rem;
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--faint);
}
.programmes ul {
  display: flex; align-items: center; justify-content: flex-end;
  flex-wrap: wrap; gap: clamp(1rem, 2.2vw, 2rem);
  margin: 0; padding: 0; list-style: none;
}
.programmes li {
  display: inline-flex; align-items: center; gap: 0.5rem; margin: 0;
  font-size: 0.92rem; font-weight: 500; letter-spacing: -0.01em;
  color: rgba(238, 242, 248, 0.82);
}
.programmes li svg { width: 17px; height: 17px; flex: none; }

@media (max-width: 860px) {
  .footer-band { flex-direction: column; align-items: flex-start; }
  .programmes, .programmes ul { text-align: left; justify-content: flex-start; }
}
@media (max-width: 560px) { .footer-mark { display: none; } }

/* ── Forms ──────────────────────────────────────────────────────────── */

.field { margin-bottom: 1.1rem; }
.field label { display: block; font-size: 0.88rem; font-weight: 560; margin-bottom: 0.4rem; }
.field input, .field textarea, .field select {
  width: 100%; padding: 0.7rem 0.85rem; font: inherit; font-size: 0.96rem;
  color: var(--ink); background: var(--ground);
  border: 1px solid var(--rule-strong); border-radius: 9px;
}
.field textarea { min-height: 8rem; resize: vertical; }
.field-note { font-size: 0.82rem; color: var(--faint); margin-top: 0.35rem; }

/* ── Reveal on scroll. Opt-in per element, and never hides content when
      JavaScript is off: the class is only added BY JavaScript. ───────── */
.js-reveal { opacity: 0; transform: translateY(14px); transition: opacity 0.5s ease, transform 0.5s ease; }
.js-reveal.is-in { opacity: 1; transform: none; }

/* THE HERO DOES NOT WAIT TO BE SCROLLED TO - it is already on screen, so it
   animates on load instead, each block a beat behind the last. This is a CSS
   animation rather than the JS reveal above precisely because the hero must
   never depend on a script: if site.js fails, every block below is still
   visible, and so is this one. */
.hero .eyebrow, .hero .hero-note, .hero h1, .hero .lede, .hero .btn-row, .hero .stat-row {
  animation: rise 0.95s var(--ease-out) both;
}
.hero .hero-note { animation-delay: 0s; }
.hero .eyebrow   { animation-delay: 0.04s; }
.hero h1         { animation-delay: 0.1s; }
.hero .lede      { animation-delay: 0.18s; }
.hero .btn-row   { animation-delay: 0.26s; }
.hero .stat-row  { animation-delay: 0.34s; }

@keyframes rise {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .hero .eyebrow, .hero .hero-note, .hero h1, .hero .lede,
  .hero .btn-row, .hero .stat-row { animation: none; }
}

.skip {
  position: absolute; left: -9999px; top: 0; background: var(--brand);
  color: #fff; padding: 0.6rem 1rem; border-radius: 0 0 8px 0; font-weight: 640; z-index: 60;
}
.skip:focus { left: 0; }

/* ── Legal / prose pages ────────────────────────────────────────────────
   Policy pages are read, not scanned, and they are frequently read on a
   phone by somebody who is mildly annoyed. Narrow measure, generous leading,
   and headings that can be linked to directly from a login screen. */
.prose { max-width: 72ch; }
.prose h2 { font-size: 1.35rem; margin-top: 2.5rem; scroll-margin-top: 90px; }
.prose h3 { margin-top: 1.75rem; }
.prose ul, .prose ol { color: var(--soft); padding-left: 1.25rem; }
.prose li { margin-bottom: 0.5rem; }
.prose table { width: 100%; border-collapse: collapse; margin: 1.25rem 0; font-size: 0.94rem; }
.prose th, .prose td { text-align: left; padding: 0.6rem 0.75rem; border-bottom: 1px solid var(--rule); vertical-align: top; }
.prose th { color: var(--faint); font-weight: 600; font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.06em; }

.toc { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 1.5rem 0 0; padding: 0; list-style: none; }
.toc a { display: inline-block; padding: 0.35rem 0.75rem; border: 1px solid var(--rule);
         border-radius: 99px; font-size: 0.86rem; text-decoration: none; color: var(--soft); }
.toc a:hover { border-color: var(--rule-strong); color: var(--ink); }

/* ══ Product pages ══════════════════════════════════════════════════════
   Big type, one idea per screen, and the product staged in the middle of
   the dark rather than boxed in a card. The pattern Apple uses works
   because each band commits to a single claim and gives it room - so the
   restraint is the design, and adding a second idea to a band undoes it. */

.stage {
  position: relative; overflow: hidden;
  padding-block: clamp(4rem, 11vw, 8rem);
  text-align: center;
}
.stage::after {
  /* Floor light under the product. Grounds the object so it reads as
     photographed rather than pasted. */
  content: ""; position: absolute; left: 50%; bottom: 8%;
  width: min(46rem, 88%); height: 12rem; transform: translateX(-50%);
  background: radial-gradient(50% 50% at 50% 50%, rgba(239, 74, 87, 0.13), transparent 72%);
  pointer-events: none;
}
.stage > .wrap { position: relative; z-index: 1; }

.display {
  font-size: clamp(2.6rem, 8vw, 5.5rem);
  font-weight: 700; line-height: 1.03; letter-spacing: -0.035em;
  margin: 0 auto 1rem; max-width: 16ch;
}
.display-sub {
  font-size: clamp(1.05rem, 2.4vw, 1.45rem); color: var(--soft);
  max-width: 48ch; margin: 0 auto;
}

.product-shot { width: min(560px, 82%); margin: clamp(2rem, 6vw, 3.5rem) auto 0; }
.product-shot img, .product-shot svg, .product-shot picture { width: 100%; height: auto; display: block; }
/* Photographic renders are light; frame them so they sit on the dark page
   as an object rather than a hole punched in it. */
.product-shot img { border-radius: var(--radius); border: 1px solid var(--rule-strong);
                    box-shadow: 0 24px 60px -24px rgba(0,0,0,.8); }

/* A band alternates side and keeps one claim. Text never crosses the
   measure even when the band is full width. */
.band { padding-block: clamp(3.5rem, 9vw, 6.5rem); }
.band .split { align-items: center; }
.band:nth-of-type(even) { background: var(--surface); }
.band-copy h2 { font-size: clamp(1.8rem, 4vw, 2.9rem); max-width: 14ch; }
.band-copy p { font-size: 1.05rem; }
.band .split > .band-media:first-child { order: -1; }
@media (min-width: 900px) {
  .band.flip .split > .band-copy { order: 2; }
}

.band-media {
  border-radius: 18px; overflow: hidden;
  background: linear-gradient(165deg, var(--surface-2), var(--ground));
  border: 1px solid var(--rule); padding: clamp(1rem, 3vw, 2rem);
}

/* Capability strip: what the product does, in words. Figures belong on a
   datasheet, where they can carry their test conditions. */
.capabilities {
  display: grid; gap: 1px; background: var(--rule);
  border: 1px solid var(--rule); border-radius: var(--radius); overflow: hidden;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
}
/* Six use cases read as two even rows of three, never five and an orphan. */
@media (min-width: 760px) { .capabilities-3 { grid-template-columns: repeat(3, 1fr); } }
.capabilities div { background: var(--ground); padding: 1.4rem 1.25rem; }
.capabilities b { display: block; font-size: 1.02rem; font-weight: 640; margin-bottom: 0.25rem; }
.capabilities span { font-size: 0.88rem; color: var(--faint); line-height: 1.5; }

/* Staggered entrance. Each child a beat behind the last, so a band arrives
   as one movement instead of four things appearing at once. */
[data-stagger] > * { transition-delay: calc(var(--i, 0) * 90ms); }

.quiet-note { font-size: 0.84rem; color: var(--faint); max-width: 52ch; margin-inline: auto; }
