/* ============================================================
   Andatem placeholder site stylesheet

   Everything below the theme blocks is written against role tokens
   only (--ground, --ink, --surface …) and never against a literal
   colour. Switching the whole site is therefore a single attribute
   on <html>:

     data-theme="anchor"  light body, deep-green nav / hero / footer
     data-theme="dark"    dark green ground, petrol cards, bone type
     data-theme="light"   bone throughout, green demoted to an accent

   Brand constants, shared by all three:
     Andatem green  #04332A   (the logo ground)
     Andatem gold   #C8AB72   (the logo glyph; == the palette --border)
     Petrol         #00405B
     Bone           #F4F1EA / surface #E8E3D6
     Taupe          #6B6559

   Contrast notes worth keeping in mind when editing: gold on bone is
   only 1.9:1, so gold is a *line* colour on light grounds, never a
   text colour. On bone, green #04332A is 12.2:1, green #0B5544 is
   7.7:1, petrol is 9.8:1 and taupe is 5.1:1, which is why the
   shipped theme puts headings in green, labels in the lifted green,
   and body copy in taupe.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Newsreader:opsz,wght@6..72,300..600&family=Karla:wght@300..700&family=IBM+Plex+Mono:wght@400;500;600&display=swap');

/* ============================================================
   THEME A: "anchor"
   Light body in the petrol/bone palette, with the Andatem green
   holding the nav, the hero band and the footer. Green still reads
   as the brand; the page itself stops being green-on-green.
   ============================================================ */

[data-theme="anchor"] {
  --ground: #F4F1EA;
  --ground-alt: #ECE8DD;
  --ground-deep: #E8E3D6;
  --surface: #FFFFFF;
  --surface-hi: #FBF9F4;
  --border: #D9CCAE;
  --border-soft: #E2DACA;

  --ink: #00405B;
  --body: #4A4640;
  --muted: #6B6559;

  --accent: #00405B;
  --accent-line: #C8AB72;
  --gold: #C8AB72;

  /* The gold glyph would sit at 1.9:1 on bone, so on light grounds
     the mark gets its own green plaque, which is how the logo is
     drawn anyway. Dark themes set this to transparent. */
  --mark-tile-bg: #04332A;
  --mark-tile-pad: 0.42em;
  --mark-tile-radius: 4px;

  --nav-bg: rgba(4, 51, 42, 0.94);
  --nav-ink: #C6D6CD;
  --nav-ink-hover: #E8D0A0;
  --nav-border: #04332A;
  --nav-cta-ink: #E8D0A0;
  --nav-cta-border: #C8AB72;
  --nav-cta-hover-bg: #C8AB72;
  --nav-cta-hover-ink: #011A15;
  --wordmark-grad: linear-gradient(100deg, #A98B52, #E8D0A0 45%, #FFF3D6 55%, #BE9E63);

  --hero-bg: #04332A;
  --hero-ink: #F4EFE3;
  --hero-body: #C6D6CD;
  --hero-meta: #93AAA0;
  --hero-meta-strong: #E8D0A0;
  --hero-glow: radial-gradient(ellipse 52% 58% at 50% 22%,
    rgba(232, 208, 160, 0.16) 0%, rgba(201, 172, 116, 0.09) 32%,
    rgba(169, 139, 82, 0.03) 55%, transparent 76%);
  --beam-mid: rgba(255, 243, 214, 0.85);
  --beam-edge: rgba(201, 172, 116, 0.35);
  --beam-glow: rgba(232, 208, 160, 0.35);

  /* Hero sits on green, so its buttons keep the dark treatment even
     though the rest of the page is light. */
  --hero-btn-bg: #C8AB72;
  --hero-btn-ink: #011A15;
  --hero-btn-hover-bg: #E8D0A0;
  --hero-btn-ghost-ink: #E8D0A0;
  --hero-btn-ghost-border: #C8AB72;
  --hero-btn-ghost-hover-bg: rgba(201, 172, 116, 0.14);

  --announce-bg: linear-gradient(180deg, rgba(201, 172, 116, 0.16) 0%, rgba(201, 172, 116, 0.04) 100%);
  --announce-border: rgba(201, 172, 116, 0.45);
  --announce-grad: linear-gradient(100deg, #9A7C41 0%, #C9AC74 18%, #F0DCAF 38%,
    #FFF8E8 50%, #F0DCAF 62%, #C9AC74 82%, #9A7C41 100%);
  --announce-dot: #E8D0A0;
  --announce-pulse: rgba(232, 208, 160, 0.6);
  --announce-when: #C6D6CD;
  --announce-rule: rgba(201, 172, 116, 0.35);
  --announce-shadow-lo: rgba(201, 172, 116, 0.14);
  --announce-shadow-hi: rgba(201, 172, 116, 0.32);

  --btn-bg: #00405B;
  --btn-ink: #F4F1EA;
  --btn-hover-bg: #00557A;
  --btn-ghost-ink: #00405B;
  --btn-ghost-border: #00405B;
  --btn-ghost-hover-bg: rgba(0, 64, 91, 0.08);

  --field-bg: #FFFFFF;
  --field-border: #C9BFA8;
  --field-ink: #2E2A24;
  --field-placeholder: #9A9182;

  --footer-bg: #04332A;
  --footer-ink: #C6D6CD;
  --footer-head: #93AAA0;
  --footer-border: #0B4437;

  --status-soon-fill: #FBEBD2;
  --status-soon-border: #A26716;
  --status-soon-ink: #7A4A06;
  --status-dev-fill: #FDF3C4;
  --status-dev-border: #7A6608;
  --status-dev-ink: #7A6608;
  --status-planned-fill: #E6EBEE;
  --status-planned-border: #6B655C;
  --status-planned-ink: #4F5D63;

  --ok: #1B4F2F;
  --alert: #85201A;
}

/* ============================================================
   THEME B: "dark"
   The approved dark ground kept, but pulled off green-on-green:
   cards go petrol, type goes bone, rules and marks go gold.
   ============================================================ */

[data-theme="dark"] {
  --ground: #04332A;
  --ground-alt: #022820;
  --ground-deep: #011A15;
  --surface: #063A50;
  --surface-hi: #084961;
  --border: #1D5C6E;
  --border-soft: #123F4E;

  --ink: #F4EFE3;
  --body: #C9C2B4;
  /* Lifted from #9C958A: the petrol card fill is much lighter than the
     green ground, and the darker taupe measured only 4.1:1 on it. This
     value clears 4.5:1 on --surface and everything darker. */
  --muted: #ABA498;

  --accent: #E8D0A0;
  --accent-line: #C8AB72;
  --gold: #C8AB72;

  --mark-tile-bg: transparent;
  --mark-tile-pad: 0;
  --mark-tile-radius: 0;

  --nav-bg: rgba(2, 40, 32, 0.9);
  --nav-ink: #B7B0A3;
  --nav-ink-hover: #E8D0A0;
  --nav-border: #0B4437;
  --nav-cta-ink: #E8D0A0;
  --nav-cta-border: #C8AB72;
  --nav-cta-hover-bg: #C8AB72;
  --nav-cta-hover-ink: #011A15;
  --wordmark-grad: linear-gradient(100deg, #A98B52, #E8D0A0 45%, #FFF3D6 55%, #BE9E63);

  --hero-bg: #04332A;
  --hero-ink: #F4EFE3;
  --hero-body: #C9C2B4;
  --hero-meta: #9C958A;
  --hero-meta-strong: #E8D0A0;
  --hero-glow: radial-gradient(ellipse 52% 58% at 50% 22%,
    rgba(232, 208, 160, 0.16) 0%, rgba(201, 172, 116, 0.09) 32%,
    rgba(169, 139, 82, 0.03) 55%, transparent 76%);
  --beam-mid: rgba(255, 243, 214, 0.85);
  --beam-edge: rgba(201, 172, 116, 0.35);
  --beam-glow: rgba(232, 208, 160, 0.35);

  --announce-bg: linear-gradient(180deg, rgba(201, 172, 116, 0.16) 0%, rgba(201, 172, 116, 0.04) 100%);
  --announce-border: rgba(201, 172, 116, 0.45);
  --announce-grad: linear-gradient(100deg, #9A7C41 0%, #C9AC74 18%, #F0DCAF 38%,
    #FFF8E8 50%, #F0DCAF 62%, #C9AC74 82%, #9A7C41 100%);
  --announce-dot: #E8D0A0;
  --announce-pulse: rgba(232, 208, 160, 0.6);
  --announce-when: #C9C2B4;
  --announce-rule: rgba(201, 172, 116, 0.35);
  --announce-shadow-lo: rgba(201, 172, 116, 0.14);
  --announce-shadow-hi: rgba(201, 172, 116, 0.32);

  --btn-bg: #C8AB72;
  --btn-ink: #011A15;
  --btn-hover-bg: #E8D0A0;
  --btn-ghost-ink: #E8D0A0;
  --btn-ghost-border: #C8AB72;
  --btn-ghost-hover-bg: rgba(201, 172, 116, 0.14);

  --field-bg: #011A15;
  --field-border: #1D5C6E;
  --field-ink: #F4EFE3;
  --field-placeholder: #6E8A94;

  --footer-bg: #011A15;
  --footer-ink: #B7B0A3;
  --footer-head: #8B8478;
  --footer-border: #0B4437;

  /* Dark-ground versions of the status palette: the light fills would
     glare, so each keeps its hue as a tinted wash with a lit border. */
  --status-soon-fill: #C8AB72;
  --status-soon-border: #C8AB72;
  --status-soon-ink: #011A15;
  --status-dev-fill: rgba(253, 243, 196, 0.12);
  --status-dev-border: rgba(224, 200, 96, 0.5);
  --status-dev-ink: #E4D08A;
  --status-planned-fill: transparent;
  --status-planned-border: #2A5A6B;
  --status-planned-ink: #9BB3BC;

  --ok: #E8D0A0;
  --alert: #E08A6A;
}

/* ============================================================
   THEME C: "light"  ← the chosen theme
   Bone everywhere, with the Andatem green carrying every role the
   pasted palette gave to petrol: headings, eyebrows, links and the
   primary button. The nav is a solid green bar, so the page opens
   on the brand colour before the bone body takes over.

   Petrol survives only inside the status ramp (--status-planned-ink),
   where it is part of the product design system rather than page
   chrome.
   ============================================================ */

[data-theme="light"] {
  --ground: #F4F1EA;
  --ground-alt: #ECE8DD;
  --ground-deep: #E8E3D6;
  --surface: #FFFFFF;
  --surface-hi: #FBF9F4;
  --border: #D9CCAE;
  --border-soft: #E2DACA;

  /* Headings take the logo green outright (12.2:1 on bone). The
     accent is lifted a step so eyebrows and links read as a distinct,
     slightly livelier tier without dropping below AA, at 7.7:1. */
  --ink: #04332A;
  --body: #4A4640;
  --muted: #6B6559;

  --accent: #0B5544;
  --accent-line: #C8AB72;
  --gold: #C8AB72;

  --mark-tile-bg: #04332A;
  --mark-tile-pad: 0.42em;
  --mark-tile-radius: 4px;

  /* Opaque, not translucent. A 0.94-alpha green over bone content
     scrolling underneath goes muddy, and it also stops the mark
     plaque behind the wordmark from blending into the bar. */
  --nav-bg: #04332A;
  --nav-ink: #C6D6CD;
  --nav-ink-hover: #E8D0A0;
  --nav-border: #04332A;
  --nav-cta-ink: #E8D0A0;
  --nav-cta-border: #C8AB72;
  --nav-cta-hover-bg: #C8AB72;
  --nav-cta-hover-ink: #011A15;
  --wordmark-grad: linear-gradient(100deg, #A98B52, #E8D0A0 45%, #FFF3D6 55%, #BE9E63);
  /* The footer is bone, where that gold lockup would sit at 1.9:1,
     so it gets the solid green treatment instead. */
  --footer-wordmark-grad: linear-gradient(100deg, #04332A, #04332A);

  --hero-bg: #F4F1EA;
  --hero-ink: #04332A;
  --hero-body: #4A4640;
  --hero-meta: #6B6559;
  --hero-meta-strong: #04332A;
  --hero-glow: radial-gradient(ellipse 52% 58% at 50% 22%,
    rgba(4, 51, 42, 0.07) 0%, rgba(11, 85, 68, 0.05) 32%,
    rgba(200, 171, 114, 0.06) 55%, transparent 76%);
  --beam-mid: rgba(4, 51, 42, 0.75);
  --beam-edge: rgba(200, 171, 114, 0.55);
  --beam-glow: rgba(4, 51, 42, 0.18);

  /* Gold on bone is 1.9:1, so the banner drops the shimmer and takes
     a flat amber that measures 6.4:1 on its own fill. A two-stop
     gradient of one colour renders solid, which keeps the shared
     rule below unchanged. */
  --announce-bg: linear-gradient(180deg, #FBEBD2 0%, #F7E2C2 100%);
  --announce-border: #A26716;
  --announce-grad: linear-gradient(100deg, #7A4A06, #7A4A06);
  --announce-dot: #A26716;
  --announce-pulse: rgba(162, 103, 22, 0.5);
  --announce-when: #6B6559;
  --announce-rule: rgba(162, 103, 22, 0.4);
  --announce-shadow-lo: rgba(162, 103, 22, 0.10);
  --announce-shadow-hi: rgba(162, 103, 22, 0.22);

  --btn-bg: #04332A;
  --btn-ink: #F4F1EA;
  --btn-hover-bg: #0B5544;
  --btn-ghost-ink: #04332A;
  --btn-ghost-border: #04332A;
  --btn-ghost-hover-bg: rgba(4, 51, 42, 0.08);

  --field-bg: #FFFFFF;
  --field-border: #C9BFA8;
  --field-ink: #2E2A24;
  --field-placeholder: #9A9182;

  --footer-bg: #ECE8DD;
  --footer-ink: #4A4640;
  --footer-head: #6B6559;
  --footer-border: #D3C9B2;

  --status-soon-fill: #FBEBD2;
  --status-soon-border: #A26716;
  --status-soon-ink: #7A4A06;
  --status-dev-fill: #FDF3C4;
  --status-dev-border: #7A6608;
  --status-dev-ink: #7A6608;
  --status-planned-fill: #E6EBEE;
  --status-planned-border: #6B655C;
  --status-planned-ink: #4F5D63;

  --ok: #1B4F2F;
  --alert: #85201A;
}

/* ============================================================
   Non-colour tokens, shared by every theme
   ============================================================ */

:root {
  --max-width: min(1320px, calc((100vw + 1040px) / 2));
  --gutter: clamp(1rem, 2.5vw, 2rem);
  --radius: 3px;
  --nav-h: 72px;
}

/* ============================================================
   Type

   Newsreader for display, Karla for body, IBM Plex Mono for the
   micro-labels. Newsreader carries the authority of a text serif
   without Fraunces' quirk; Karla keeps enough personality to stay
   approachable; Plex Mono is warmer and less engineering-flavoured
   than JetBrains Mono.

   The wordmark uses Karla at 300 rather than a fourth family; at
   0.22em tracking the letterforms do the work.

   Two other pairings were trialled and dropped: Source Serif 4 /
   Source Sans 3 (more institutional) and Literata / Figtree (more
   casual). Re-adding either means extending the @import above as
   well, or the faces silently fall back to a system stack.
   ============================================================ */

:root {
  --font-display: 'Newsreader', Georgia, serif;
  --font-body: 'Karla', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono: 'IBM Plex Mono', 'Courier New', monospace;
  --font-logo: 'Karla', -apple-system, sans-serif;
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* Anchor targets clear the sticky bar instead of landing behind it. */
  scroll-padding-top: calc(var(--nav-h) + 1rem);
  background: var(--ground);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  font-family: var(--font-body);
  background: var(--ground);
  color: var(--body);
  line-height: 1.6;
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 0.2em; }

a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

img { max-width: 100%; display: block; }

.wrap {
  max-width: var(--max-width);
  margin: 0 auto;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}

/* Available to screen readers only. */
.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;
}

.skip-link {
  position: absolute;
  left: 50%;
  top: -100px;
  transform: translateX(-50%);
  z-index: 200;
  background: var(--gold);
  color: #011A15;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  padding: 0.7rem 1.2rem;
  border-radius: 0 0 var(--radius) var(--radius);
  transition: top 0.15s ease;
}

.skip-link:focus { top: 0; text-decoration: none; }

/* ============================================================
   The mark plaque

   One transparent gold PNG serves every theme: on light grounds the
   tile paints the logo's own green behind it, on dark grounds the
   tile is transparent and the glyph sits directly on the page.
   ============================================================ */

.mark-tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--mark-tile-bg);
  padding: var(--mark-tile-pad);
  border-radius: var(--mark-tile-radius);
  flex-shrink: 0;
  line-height: 0;
}

/* ============================================================
   Navigation
   ============================================================ */

.site-nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--nav-bg);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--nav-border);
}

.site-nav .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  height: var(--nav-h);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  flex-shrink: 0;
}

.wordmark:hover { text-decoration: none; }
.wordmark img { height: 30px; width: 30px; }

.wordmark-text {
  font-family: var(--font-logo);
  font-weight: 300;
  font-size: 1.15rem;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  /* letter-spacing appends a trailing gap after the last glyph;
     reclaim it so the lockup sits optically centred beside the mark. */
  margin-right: -0.22em;
  background: var(--wordmark-grad);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.nav-links {
  display: flex;
  gap: clamp(1.1rem, 2.4vw, 2.1rem);
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-links a {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--nav-ink);
  text-transform: lowercase;
  letter-spacing: 0.02em;
  transition: color 0.15s ease;
  white-space: nowrap;
}

.nav-links a:hover { color: var(--nav-ink-hover); text-decoration: none; }

.nav-cta {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  padding: 0.5rem 1rem;
  border: 1px solid var(--nav-cta-border);
  border-radius: var(--radius);
  color: var(--nav-cta-ink) !important;
  transition: background 0.15s ease, color 0.15s ease;
}

.nav-cta:hover {
  background: var(--nav-cta-hover-bg);
  color: var(--nav-cta-hover-ink) !important;
}

.nav-toggle {
  display: none;
  background: none;
  border: 1px solid var(--nav-cta-border);
  border-radius: var(--radius);
  color: var(--nav-cta-ink);
  cursor: pointer;
  padding: 0.45rem;
  line-height: 0;
}

@media (max-width: 860px) {
  .nav-links {
    position: fixed;
    top: var(--nav-h);
    left: 0;
    right: 0;
    background: var(--nav-bg);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    border-bottom: 1px solid var(--nav-border);
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.25s ease;
  }
  .nav-links.open { max-height: 460px; }
  .nav-links a {
    display: block;
    padding: 1rem var(--gutter);
    border-bottom: 1px solid var(--nav-border);
  }
  .nav-links .nav-cta {
    border: none;
    border-bottom: 1px solid var(--nav-border);
    border-radius: 0;
  }
  .nav-toggle { display: block; }
}

/* ============================================================
   Typography
   ============================================================ */

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 500;
  color: var(--ink);
  line-height: 1.15;
  margin: 0;
  letter-spacing: -0.01em;
}

h1 { font-size: clamp(2.15rem, 5vw, 3.9rem); font-weight: 400; }
h2 { font-size: clamp(1.75rem, 3.2vw, 2.6rem); }
h3 { font-size: 1.28rem; }

p { margin: 0 0 1rem; color: var(--body); }
p:last-child { margin-bottom: 0; }

.lede {
  font-size: 1.15rem;
  color: var(--body);
  max-width: 46ch;
  line-height: 1.6;
}

strong { color: var(--ink); font-weight: 600; }

.eyebrow {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--accent);
  text-transform: lowercase;
  letter-spacing: 0.08em;
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  margin-bottom: 0.9rem;
}

/* A short gold rule under each section eyebrow, the one place gold
   carries meaning on a light ground without having to be legible. */
.eyebrow::after {
  content: '';
  width: 2.2em;
  height: 1px;
  background: var(--accent-line);
}

.section-head { max-width: 60ch; margin-bottom: 1rem; }
.section-head.center-text { margin-left: auto; margin-right: auto; }
.section-head.center-text .eyebrow::after { display: none; }
.section-head h2 + .lede { margin-top: 1rem; }
.section-head.center-text .lede { margin-left: auto; margin-right: auto; }

section { padding: clamp(3.5rem, 8vw, 6.5rem) 0; }

.section-dim { background: var(--ground-alt); }
.section-deep { background: var(--ground-deep); }

.center-text { text-align: center; }

/* ============================================================
   Hero
   Layers, back to front: a broad radial wash, a hairline "beam"
   standing in for the balance arm of the scales, then content.
   ============================================================ */

/* The banner is the first thing in the hero now that the mark has been
   removed, and it is meant to sit up under the nav bar, so the top
   padding is only enough to clear the beam hairline, not the generous
   opener a logo lockup needed. */
.hero {
  position: relative;
  overflow: hidden;
  background: var(--hero-bg);
  padding-top: clamp(1.5rem, 3vw, 2.25rem);
  padding-bottom: clamp(3rem, 7vw, 5.5rem);
}

.hero-glow {
  position: absolute;
  top: -34%;
  left: 50%;
  transform: translateX(-50%);
  width: min(1180px, 140%);
  height: 108%;
  pointer-events: none;
  background: var(--hero-glow);
  filter: blur(18px);
  animation: fade-in 1.1s ease-out both;
}

/* The balance arm: a hairline that brightens at the fulcrum. */
.hero-beam {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: min(760px, 82%);
  height: 1px;
  pointer-events: none;
  background: linear-gradient(to right,
    transparent 0%,
    var(--beam-edge) 22%,
    var(--beam-mid) 50%,
    var(--beam-edge) 78%,
    transparent 100%);
  box-shadow: 0 0 18px var(--beam-glow);
  animation: beam-strike 1.2s ease-out both;
}

.hero .wrap { position: relative; }

.hero h1 {
  max-width: 20ch;
  margin: 0 auto;
  color: var(--hero-ink);
}

.hero .lede {
  margin: 1.4rem auto 0;
  max-width: 58ch;
  font-size: 1.2rem;
  color: var(--hero-body);
}

.hero-actions {
  margin-top: 2.25rem;
  display: flex;
  gap: 0.9rem;
  flex-wrap: wrap;
  justify-content: center;
}

/* Experience line. Sits below the actions as a quiet credential
   rather than a second badge competing with the banner above. */
.hero-cred {
  margin-top: 2rem;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  color: var(--hero-meta);
}

.hero-cred strong { color: var(--hero-meta-strong); font-weight: 500; }

@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes beam-strike {
  0% { opacity: 0; transform: translateX(-50%) scaleX(0.3); }
  60% { opacity: 1; transform: translateX(-50%) scaleX(1); }
  100% { opacity: 1; transform: translateX(-50%) scaleX(1); }
}

/* ============================================================
   Announcement banner: the "coming soon" line, promoted into its
   own object so it reads as a banner and not as a label attached
   to the headline underneath it.
   ============================================================ */

.announce {
  display: inline-flex;
  align-items: center;
  gap: 0.8em;
  margin: 0 auto 2.25rem;
  padding: 0.75rem clamp(1.2rem, 3vw, 2.2rem);
  border: 1px solid var(--announce-border);
  border-radius: 999px;
  background: var(--announce-bg);
  animation: announce-rise 0.7s ease-out 0.3s both,
             announce-glow 3.4s ease-in-out 1s infinite;
}

.announce-text {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: clamp(0.95rem, 2.6vw, 1.85rem);
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.24em;
  margin-right: -0.24em;
  /* A highlight travelling across the glyphs. Wider than the text
     (background-size) so there is somewhere to travel from. Light
     themes set a single-colour gradient, which renders flat and
     makes the sweep a no-op. */
  background: var(--announce-grad);
  background-size: 260% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: announce-sweep 4.6s linear infinite;
}

.announce-dot {
  width: 0.4em;
  height: 0.4em;
  font-size: clamp(0.95rem, 2.6vw, 1.85rem);
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--announce-dot);
  animation: announce-pulse 2.6s ease-out infinite;
}

/* The date sits inside the pill but steps down in weight, so the
   banner still reads "coming soon" first and the year second. */
.announce-when {
  font-family: var(--font-mono);
  font-size: clamp(0.66rem, 1.3vw, 0.86rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--announce-when);
  padding-left: 0.85em;
  border-left: 1px solid var(--announce-rule);
  white-space: nowrap;
}

/* On a narrow screen the pill is an inline-flex row of three nowrap
   children, so it happily grows past the wrap's content box and only
   stays inside the viewport by luck. Break the release line onto its
   own row instead, and trade the vertical rule for a horizontal one
   so it still reads as a separate piece of information. */
@media (max-width: 560px) {
  .announce {
    max-width: 100%;
    flex-wrap: wrap;
    justify-content: center;
    row-gap: 0.55em;
  }
  .announce-when {
    flex-basis: 100%;
    padding-left: 0;
    padding-top: 0.55em;
    border-left: none;
    border-top: 1px solid var(--announce-rule);
    white-space: normal;
    text-align: center;
  }
}

@keyframes announce-sweep {
  from { background-position: 160% 0; }
  to { background-position: -60% 0; }
}

@keyframes announce-glow {
  0%, 100% { box-shadow: 0 0 26px var(--announce-shadow-lo); }
  50% { box-shadow: 0 0 54px var(--announce-shadow-hi); }
}

@keyframes announce-pulse {
  0% { box-shadow: 0 0 0 0 var(--announce-pulse); }
  70% { box-shadow: 0 0 0 14px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

@keyframes announce-rise {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

/* The global reduced-motion rule collapses animations to their end
   frame, which for the sweep parks the gradient off to one side and
   leaves the text muddy. Pin it mid-sweep so it still reads as lit. */
@media (prefers-reduced-motion: reduce) {
  .announce, .announce-dot { animation: none; }
  .announce-text { animation: none; background-position: 50% 0; }
  .announce { box-shadow: 0 0 30px var(--announce-shadow-hi); }
  .hero-beam { transform: translateX(-50%) scaleX(1); opacity: 1; }
}

/* ============================================================
   Buttons
   ============================================================ */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-family: var(--font-mono);
  font-size: 0.86rem;
  padding: 0.85rem 1.5rem;
  border-radius: var(--radius);
  border: 1px solid transparent;
  transition: background 0.15s ease, color 0.15s ease, transform 0.15s ease;
  cursor: pointer;
}

.btn:hover { text-decoration: none; transform: translateY(-1px); }

.btn-primary {
  background: var(--btn-bg);
  border-color: var(--btn-bg);
  color: var(--btn-ink) !important;
  font-weight: 500;
}

.btn-primary:hover {
  background: var(--btn-hover-bg);
  border-color: var(--btn-hover-bg);
}

.btn-ghost {
  background: transparent;
  border-color: var(--btn-ghost-border);
  color: var(--btn-ghost-ink) !important;
}

.btn-ghost:hover { background: var(--btn-ghost-hover-bg); }

/* The hero band carries its own ground in themes that anchor it in
   green, so its buttons fall back to the page treatment only when a
   theme has not set a hero-specific one. */
.hero .btn-primary {
  background: var(--hero-btn-bg, var(--btn-bg));
  border-color: var(--hero-btn-bg, var(--btn-bg));
  color: var(--hero-btn-ink, var(--btn-ink)) !important;
}

.hero .btn-primary:hover {
  background: var(--hero-btn-hover-bg, var(--btn-hover-bg));
  border-color: var(--hero-btn-hover-bg, var(--btn-hover-bg));
}

.hero .btn-ghost {
  border-color: var(--hero-btn-ghost-border, var(--btn-ghost-border));
  color: var(--hero-btn-ghost-ink, var(--btn-ghost-ink)) !important;
}

.hero .btn-ghost:hover {
  background: var(--hero-btn-ghost-hover-bg, var(--btn-ghost-hover-bg));
}

/* ============================================================
   Pillar grid: what Andatem is for. Three across, because these
   are simultaneous commitments rather than sequential steps.
   ============================================================ */

.pillar-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  margin-top: 2.75rem;
}

.pillar {
  background: var(--surface);
  padding: clamp(1.75rem, 3vw, 2.6rem);
}

.pillar-icon {
  width: 42px;
  height: 42px;
  border-radius: var(--radius);
  border: 1px solid var(--accent-line);
  background: var(--ground-alt);
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 1.35rem;
}

.pillar h3 { margin-bottom: 0.6rem; }
.pillar p { font-size: 0.96rem; }

@media (max-width: 900px) {
  .pillar-grid { grid-template-columns: 1fr; }
}

/* ============================================================
   Commitments: the four promises the suite is run on. Two across,
   because they are a set of equals rather than a ranked list.
   ============================================================ */

.values-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  margin-top: 2.75rem;
}

.value-card {
  background: var(--surface);
  padding: clamp(1.75rem, 3vw, 2.5rem);
}

.value-card .eyebrow { margin-bottom: 1rem; font-size: 0.8rem; }
.value-card h3 { margin-bottom: 0.6rem; font-size: 1.18rem; }
.value-card p { font-size: 0.96rem; }

@media (max-width: 720px) {
  .values-grid { grid-template-columns: 1fr; }
}

/* The brand line, closing the commitments section. Display type rather
   than a callout box: it is the payoff of the four promises above, not
   another item alongside them. Roman, not italic, because the display face is
   loaded without an italic axis, and a synthesised slant on a serif
   this size is obvious. */
.tagline {
  margin: clamp(2.5rem, 5vw, 3.5rem) auto 0;
  max-width: 24ch;
  text-align: center;
  font-family: var(--font-display);
  font-size: clamp(1.45rem, 3vw, 2.1rem);
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--ink);
}

/* Short gold rule above it, the same role gold plays under the
   section eyebrows, marking a line as brand rather than body. */
.tagline::before {
  content: '';
  display: block;
  width: 3.5rem;
  height: 1px;
  margin: 0 auto 1.5rem;
  background: var(--accent-line);
}

/* Callout note under the commitments. Currently unused, because the
   parent-company reference was pulled from the page, but kept ready
   for when that link comes back. */
.parent-note {
  margin-top: 2rem;
  padding: 1.5rem 1.75rem;
  border: 1px solid var(--border-soft);
  border-left: 2px solid var(--accent-line);
  border-radius: var(--radius);
  background: var(--surface);
  font-size: 0.97rem;
}

/* ============================================================
   Product cards
   ============================================================ */

/* Explicit column counts rather than auto-fit, so a row is never left
   with a single stranded card. Three products means three across or
   one across, since a two-column step would orphan the third, which is the
   same breakpoint .pillar-grid uses for its three. Revisit this if the
   suite grows back to four. */
.product-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
  margin-top: 2.75rem;
}

@media (max-width: 900px) {
  .product-grid { grid-template-columns: 1fr; }
}

.product-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: clamp(1.6rem, 2.6vw, 2rem);
  background: var(--surface);
  display: flex;
  flex-direction: column;
  transition: border-color 0.15s ease, transform 0.15s ease, background 0.15s ease;
}

.product-card:hover {
  border-color: var(--accent-line);
  background: var(--surface-hi);
  transform: translateY(-2px);
}

/* Icon and status pill share a row, pill pushed to the right edge.
   The children carry no bottom margin of their own; the spacing is
   moved onto the row, or the taller of the two would set the gap. */
.product-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.35rem;
}

.product-icon {
  width: 46px;
  height: 46px;
  border-radius: var(--radius);
  background: var(--ground-alt);
  border: 1px solid var(--accent-line);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
  flex-shrink: 0;
  overflow: hidden;
}

/* The marks are gold on transparent, so on a light card they need
   the green plaque; .mark-tile supplies it and fills the well. */
.product-icon .mark-tile {
  width: 100%;
  height: 100%;
  border-radius: 0;
  padding: 0.34rem;
}

.product-icon img { width: 100%; height: 100%; object-fit: contain; }

.status-badge {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  padding: 0.28rem 0.65rem;
  border-radius: 999px;
  width: fit-content;
  flex-shrink: 0;
  text-transform: lowercase;
  letter-spacing: 0.02em;
  border: 1px solid;
}

/* Mapped onto the product design system's own status ramp: "coming
   soon" takes the locked amber, "in development" the draft yellow,
   "planned" the neutral submitted grey. */
.status-soon {
  background: var(--status-soon-fill);
  border-color: var(--status-soon-border);
  color: var(--status-soon-ink);
  font-weight: 500;
}

.status-progress {
  background: var(--status-dev-fill);
  border-color: var(--status-dev-border);
  color: var(--status-dev-ink);
}

.status-planned {
  background: var(--status-planned-fill);
  border-color: var(--status-planned-border);
  color: var(--status-planned-ink);
}

/* Opt a badge out of the lowercasing. The generic labels read well in
   lowercase, but anything carrying a proper noun (a month, a product
   name) needs its own capitalisation kept. */
.status-badge.is-cased { text-transform: none; }

.product-card h3 { margin-bottom: 0.5rem; }

.product-kind {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin: 0 0 0.85rem;
  text-transform: lowercase;
}

/* flex-grow on the description is what keeps the release lines
   bottom-aligned across cards of differing text length. */
.product-card p.product-desc { flex-grow: 1; font-size: 0.95rem; }

/* Scoped to .product-card because `.product-card p` (0,1,1) would
   otherwise outrank a lone class and win font-size and flex-grow. */
.product-card .product-release {
  flex-grow: 0;
  margin: 1.35rem 0 0;
  padding-top: 1.1rem;
  border-top: 1px solid var(--border-soft);
  font-family: var(--font-mono);
  font-size: 0.76rem;
  letter-spacing: 0.02em;
  color: var(--muted);
}

.product-card .product-release span { color: var(--ink); font-weight: 500; }

/* ============================================================
   Contact form
   ============================================================ */

.contact-form {
  max-width: 580px;
  margin: 2rem auto 0;
  text-align: left;
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

@media (max-width: 620px) {
  .form-row { grid-template-columns: 1fr; gap: 0; }
}

.form-group { margin-bottom: 1.1rem; }

.form-group label {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--body);
  margin-bottom: 0.45rem;
}

.form-group input,
.form-group textarea,
.form-group select {
  width: 100%;
  font-family: var(--font-body);
  font-size: 1rem;
  padding: 0.75rem 0.95rem;
  border: 1px solid var(--field-border);
  border-radius: var(--radius);
  background: var(--field-bg);
  color: var(--field-ink);
  transition: border-color 0.15s ease;
}

.form-group input::placeholder,
.form-group textarea::placeholder { color: var(--field-placeholder); }

.form-group input:focus,
.form-group textarea:focus,
.form-group select:focus {
  outline: none;
  border-color: var(--accent);
}

.form-group textarea { resize: vertical; min-height: 118px; }

/* Honeypot wrapper: off-screen rather than display:none or
   visibility:hidden, both of which bots commonly detect and skip. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* min-height reserves the line so the button does not jump when a
   result message appears. */
.form-status {
  margin: 1rem 0 0;
  min-height: 1.4em;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  letter-spacing: 0.02em;
  color: var(--muted);
}

.form-status.is-ok { color: var(--ok); }
.form-status.is-error { color: var(--alert); }

.char-count {
  margin: 0.4rem 0 0;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  color: var(--muted);
  text-align: right;
}

/* Warm up as the limit approaches, so running out is not a surprise. */
.char-count.is-near { color: var(--status-dev-ink); }
.char-count.is-full { color: var(--status-soon-ink); }

.contact-direct {
  margin-top: 1.75rem;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  color: var(--muted);
}

/* ============================================================
   Footer
   ============================================================ */

/* A single centred stack now that the link columns are gone: the brand
   lockup, then the summary, then the legal line. Nothing is left to sit
   opposite anything, so the old two-column flex row would just have
   stranded one block against the left edge.

   No border-top: the footer is separated from the contact section the
   same way every other section boundary on the page is, by taking the
   opposite ground tone: --footer-bg is --ground-alt while #contact,
   the last section above it, sits on the base ground. The whole page
   alternates base/alt from the hero down, so adding or removing a
   section flips every band after it. Re-check the run if you do. */
.site-footer {
  background: var(--footer-bg);
  color: var(--footer-ink);
  padding: 3rem 0 2.25rem;
  text-align: center;
}

.footer-lockup {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
}

/* Deliberately uncapped. Everywhere else on the page a reading measure
   is enforced, but this is one closing line rather than a paragraph to
   read through, and holding it to a measure stacked it three deep under
   the lockup. Left to the container width it resolves to one or two. */
.footer-summary {
  margin: clamp(1.4rem, 3vw, 1.9rem) auto 0;
  font-size: 0.9rem;
  color: var(--footer-ink);
}

.footer-tagline {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.05rem;
  color: var(--ink);
}

/* The nav and the footer do not always sit on the same ground; in the
   light theme the bar is green and the footer is bone, and a gold
   lockup that reads well on one is illegible on the other. Themes that
   need them to differ set --footer-wordmark-grad; the rest fall back. */
.site-footer .wordmark-text {
  background: var(--footer-wordmark-grad, var(--wordmark-grad));
  -webkit-background-clip: text;
  background-clip: text;
}

/* The rule that used to close the brand block now opens the legal
   line, since the lockup moved down to sit directly on top of it. */
.footer-bottom {
  margin-top: clamp(1.75rem, 3.5vw, 2.25rem);
  padding-top: 1.6rem;
  border-top: 1px solid var(--footer-border);
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
  font-size: 0.8rem;
  font-family: var(--font-mono);
  color: var(--footer-head);
}

/* Once the row wraps, space-between puts each line on its own left
   edge, which reads as misaligned against the centred footer above it.
   Centre them instead. */
@media (max-width: 560px) {
  .footer-bottom { justify-content: center; }
}

/* ============================================================
   Style variants

   Selected by data-style on <html>, independent of data-theme. These
   change shape, alignment, density and depth only: not one colour
   token is touched, so every variant renders in the same green / bone
   / gold palette.

     refined    the base, applied when no data-style is set: bordered
                cards on alternating bands, centred heads, hairlines
     ledger     flat and left-aligned, square corners, content
                separated by rules rather than boxes
     elevated   rounded and shadowed, cards lifted off the ground,
                airier spacing  ← shipping
   ============================================================ */

/* ---------- ledger ------------------------------------------------
   Square, left-aligned and boxless. Structure comes from rules and
   alignment the way a well-set document does, not from containers.
   ------------------------------------------------------------------ */

[data-style="ledger"] { --radius: 0; }

[data-style="ledger"] .hero,
[data-style="ledger"] .section-head,
[data-style="ledger"] #contact .wrap { text-align: left; }

[data-style="ledger"] .announce,
[data-style="ledger"] .hero h1,
[data-style="ledger"] .hero .lede,
[data-style="ledger"] .section-head,
[data-style="ledger"] .section-head .lede { margin-left: 0; margin-right: 0; }

[data-style="ledger"] .hero-actions { justify-content: flex-start; }

/* The rule under an eyebrow is the motif this variant leans on, so it
   is restored on centred heads where the default suppresses it. */
[data-style="ledger"] .section-head.center-text .eyebrow::after { display: inline-block; }

/* Cards become rows: a heavy top rule, no fill, no frame. */
[data-style="ledger"] .product-card,
[data-style="ledger"] .tagline {
  background: transparent;
  border: none;
  border-top: 2px solid var(--ink);
  padding: 1.4rem 0 0;
}

[data-style="ledger"] .product-card:hover {
  background: transparent;
  transform: none;
  border-top-color: var(--accent-line);
}

[data-style="ledger"] .tagline {
  max-width: none;
  text-align: left;
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
}
[data-style="ledger"] .tagline::before { display: none; }

/* These two grids paint --border across the whole element and let a 1px
   gap show it through as hairlines, which means the cell fill is what
   hides it. Dropping that fill alone turns the entire grid into a solid
   gold block, so the grid background has to come off with it and the
   rules move onto the cells themselves. */
[data-style="ledger"] .pillar-grid,
[data-style="ledger"] .values-grid {
  background: transparent;
  border: none;
  overflow: visible;
  column-gap: clamp(1.5rem, 3vw, 2.5rem);
  row-gap: clamp(2rem, 4vw, 2.75rem);
}

[data-style="ledger"] .pillar,
[data-style="ledger"] .value-card {
  background: transparent;
  border-top: 2px solid var(--ink);
  padding: 1.4rem 0 0;
}

[data-style="ledger"] .product-icon,
[data-style="ledger"] .pillar-icon { border-radius: 0; }

[data-style="ledger"] .status-badge {
  border-radius: 0;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.62rem;
}

[data-style="ledger"] .announce { border-radius: 0; }
[data-style="ledger"] .contact-form { margin-left: 0; }
[data-style="ledger"] .site-footer { text-align: left; }
[data-style="ledger"] .footer-lockup { align-items: flex-start; }

/* ---------- elevated ----------------------------------------------
   Rounded and shadowed. Cards lift off the ground instead of being
   drawn onto it, and the grids give up their shared hairlines so each
   card can carry its own edge.
   ------------------------------------------------------------------ */

[data-style="elevated"] { --radius: 14px; }

[data-style="elevated"] .product-card,
[data-style="elevated"] .parent-note,
[data-style="elevated"] .pillar,
[data-style="elevated"] .value-card {
  border-radius: 16px;
  border-color: transparent;
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(4, 51, 42, 0.05),
              0 10px 28px rgba(4, 51, 42, 0.07);
}

[data-style="elevated"] .product-card:hover {
  border-color: transparent;
  box-shadow: 0 2px 4px rgba(4, 51, 42, 0.06),
              0 18px 44px rgba(4, 51, 42, 0.12);
}

/* These two grids paint their own background through a 1px gap to make
   hairlines. Shadowed cards need real gutters and an unclipped box, so
   the shared background, border and overflow all come off. */
[data-style="elevated"] .pillar-grid,
[data-style="elevated"] .values-grid {
  background: transparent;
  border: none;
  overflow: visible;
  gap: 1.25rem;
}

[data-style="elevated"] .product-grid { gap: 1.75rem; }

[data-style="elevated"] .pillar,
[data-style="elevated"] .value-card,
[data-style="elevated"] .product-card { padding: clamp(1.9rem, 3vw, 2.5rem); }

[data-style="elevated"] .btn { border-radius: 999px; padding: 0.95rem 1.8rem; }
[data-style="elevated"] .product-icon,
[data-style="elevated"] .pillar-icon { border-radius: 12px; }
[data-style="elevated"] .mark-tile { border-radius: 8px; }

[data-style="elevated"] .form-group input,
[data-style="elevated"] .form-group textarea { border-radius: 10px; }

[data-style="elevated"] .form-group input,
[data-style="elevated"] .form-group textarea,
[data-style="elevated"] .contact-form {
  box-shadow: none;
}
