/* ==========================================================================
   X Made — styles.css
   Independent software studio brand site.
   Bold, editorial, technical-but-restrained. Warm white + deep ink,
   one petrol-teal accent, an expressive brushstroke X.
   ========================================================================== */

/* ==========================================================================
   Fonts — self-hosted
   Previously pulled from fonts.googleapis.com, whose stylesheet was a
   render-blocking request on a third origin: a DNS lookup, TCP connect and
   TLS handshake had to finish before the page could paint. Serving these
   from our own origin removes that hop entirely, and keeps visitor IP
   addresses away from a third party.

   Both faces are variable fonts, so one file per subset covers every weight
   the site uses (Inter 400-800, JetBrains Mono 400-600). The unicode-range
   rules mean an English page only ever downloads the two latin files;
   latin-ext is fetched on demand and usually never.
   ========================================================================== */

/* latin */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
    U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* latin-ext */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../fonts/inter-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

/* latin */
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
    U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* latin-ext */
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
    U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}

/* ---- Design tokens ---- */
:root {
  --ink: #111318;
  --ink-card: #15171c;
  --ink-border: #262a31;
  --white: #ffffff;
  --offwhite: #f7f7f5;
  --grey-soft: #e9e9e6;
  --grey-mid: #8b8e93;
  /* Darker secondary text: --grey-mid lacks contrast at small sizes. */
  --grey-text: #6b6f76;
  --grey-on-dark: #a7aab0;
  --teal: #0f6b6d;
  /* The accent lightened for dark grounds. --teal measures 2.9:1 on --ink and
     2.9:1 on --ink-card, which fails AA for text and the 3:1 floor for icons
     and focus rings. This value was already hard-coded on the dark header; it
     is a token now so every dark section shares one accent. */
  --teal-on-dark: #5fb8b3;

  --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    Helvetica, Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas,
    monospace;

  --container: 1200px;
  --container-narrow: 720px;

  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2.5rem;
  --space-5: 4rem;
  --space-6: 6rem;
  --space-7: 9rem;

  --radius: 4px;
  --radius-card: 14px;
  --border: 1px solid var(--grey-soft);

  --ease: cubic-bezier(0.4, 0, 0.2, 1);
}

/* Dark sections re-point --teal at the lighter variant, so every accent inside
   them — link text, eyebrows, icon strokes, hairlines, focus rings — picks it
   up without a per-rule override.
   The phone mockups and the icon walls are deliberately not listed: they
   simulate the product's own interface, where the teal either carries white
   key labels or stands for an accent colour SUMX actually ships. */
.strip,
.products,
.studio,
.site-footer,
.page-dark-nav .site-header {
  --teal: var(--teal-on-dark);
}

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

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  min-height: 100svh;
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--white);
  line-height: 1.6;
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

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

/* Lets every image carry width/height attributes for aspect-ratio (and so
   avoid layout shift) without the height attribute fighting a CSS width. */
img {
  height: auto;
}

a {
  color: inherit;
  text-decoration: none;
}

/* Ordered lists are reset alongside unordered ones. Every <ol> on the site
   draws its own numbering with a counter, so leaving the native markers on
   rendered each item twice ("1. 1. Getting started"). */
ul,
ol {
  list-style: none;
  padding: 0;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

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

/* ---- Utilities ---- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--space-3);
}

.narrow {
  max-width: var(--container-narrow);
}

.visually-hidden {
  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;
  top: -100%;
  left: var(--space-2);
  z-index: 100;
  background: var(--ink);
  color: var(--white);
  padding: 0.75rem 1.25rem;
  border-radius: var(--radius);
  transition: top 0.2s var(--ease);
}

.skip-link:focus {
  top: var(--space-2);
}

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

.accent-teal {
  color: var(--teal);
}

/* ---- Type ---- */
h1,
h2,
h3 {
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.07;
}

h2 {
  font-size: clamp(1.9rem, 2.4vw + 1.1rem, 2.75rem);
}

h3 {
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.eyebrow {
  display: block;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--teal);
  margin-bottom: var(--space-2);
}

.section-lead {
  color: var(--grey-text);
  font-size: 1.05rem;
  max-width: 42ch;
}

.text-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  color: var(--teal);
  font-weight: 600;
  font-size: 0.95rem;
}

/* Standalone calls to action sit at 24px, which is a small thing to hit with a
   thumb. Given height only on mobile so desktop rhythm is unchanged. */
@media (max-width: 767px) {
  .text-link {
    min-height: 44px;
  }
}

.text-link span {
  display: inline-block;
  transition: transform 0.2s var(--ease);
}

.text-link:hover span,
.text-link:focus-visible span {
  transform: translateX(4px);
}

/* ---- Buttons ---- */
.button-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.85rem 1.6rem;
  border-radius: 999px;
  font-size: 0.95rem;
  font-weight: 600;
  transition: transform 0.2s var(--ease), border-color 0.2s var(--ease),
    background-color 0.2s var(--ease);
}

.btn span {
  display: inline-block;
  transition: transform 0.2s var(--ease);
}

.btn:hover span,
.btn:focus-visible span {
  transform: translateX(3px);
}

.btn-primary {
  background: var(--ink);
  color: var(--offwhite);
  border: 1px solid var(--ink);
}

.btn-primary:hover,
.btn-primary:focus-visible {
  transform: translateY(-1px);
}

.btn-secondary {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--grey-soft);
}

.btn-secondary:hover,
.btn-secondary:focus-visible {
  border-color: var(--teal);
  color: var(--teal);
}

/* ---- Reveal-on-scroll (progressive enhancement) ---- */
.reveal {
  opacity: 1;
  transform: none;
}

html.js .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}

html.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html.js .reveal {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* ==========================================================================
   Header
   ========================================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(247, 247, 245, 0.92);
  backdrop-filter: saturate(140%) blur(8px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}

.site-header.is-scrolled {
  border-bottom-color: var(--grey-soft);
  box-shadow: 0 1px 0 rgba(17, 19, 24, 0.02);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-block: var(--space-3);
  gap: var(--space-3);
}

.logo {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.logo-mark {
  height: 30px;
  width: auto;
}

.logo-word {
  font-size: 1.3rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1;
  padding-top: 0.1em;
}

/* Nav toggle (mobile) */
.nav-toggle {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  /* 44px is the smallest comfortable touch target. */
  width: 44px;
  height: 44px;
  border-radius: var(--radius);
}

.nav-toggle-bar {
  width: 20px;
  height: 2px;
  background: var(--ink);
  transition: transform 0.25s var(--ease), opacity 0.25s var(--ease);
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bar:first-child {
  transform: translateY(3.5px) rotate(45deg);
}

/* :last-child matched nothing here — the button ends with a visually-hidden
   "Menu" label, so the second bar never rotated and the open state rendered as
   one diagonal stroke crossed by a stray horizontal bar instead of an X. */
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2) {
  transform: translateY(-3.5px) rotate(-45deg);
}

.primary-nav ul {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.primary-nav a {
  font-size: 0.95rem;
  font-weight: 500;
  position: relative;
  padding-block: 0.25rem;
}

.primary-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--teal);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s var(--ease);
}

.primary-nav a:hover::after,
.primary-nav a:focus-visible::after,
.primary-nav a[aria-current="page"]::after {
  transform: scaleX(1);
}

.primary-nav a[aria-current="page"] {
  color: var(--teal);
}

@media (max-width: 767px) {
  .nav-toggle {
    display: flex;
  }

  /* The wordmark is the route home; 30px was under the comfortable minimum. */
  .logo {
    min-height: 44px;
  }

  .primary-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--offwhite);
    border-bottom: 1px solid var(--grey-soft);
    overflow: hidden;
    max-height: 0;
    transition: max-height 0.3s var(--ease);
  }

  .primary-nav.is-open {
    /* Was a flat 340px, which is fine at default text size but clipped 191px
       off the menu at 200% browser text zoom, putting Contact out of reach.
       rem tracks the user's text size, and the vh cap keeps the panel inside
       the screen; whatever still will not fit can be scrolled to. */
    max-height: min(70vh, 34rem);
    overflow-y: auto;
  }

  .primary-nav ul {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    padding: var(--space-2) var(--space-3) var(--space-3);
  }

  .primary-nav li {
    width: 100%;
  }

  .primary-nav a {
    display: block;
    padding-block: var(--space-2);
  }
}

@media (min-width: 768px) {
  .nav-toggle {
    display: none;
  }
}

/* ==========================================================================
   Hero
   ========================================================================== */
.hero {
  position: relative;
  background: var(--offwhite);
  overflow: hidden;
}

/* Decorative background: dot grid + faint code fragments */
.hero-bg {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

.code-grid {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(
    circle,
    rgba(139, 142, 147, 0.4) 1px,
    transparent 1.4px
  );
  background-size: 34px 34px;
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent,
    black 12%,
    black 88%,
    transparent
  );
  mask-image: linear-gradient(
    to bottom,
    transparent,
    black 12%,
    black 88%,
    transparent
  );
  opacity: 0.6;
}

.code-frag {
  position: absolute;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  line-height: 1.6;
  color: rgba(17, 19, 24, 0.32);
  white-space: pre;
  display: none;
}

.code-frag .tok {
  color: var(--teal);
  opacity: 0.7;
}

@media (min-width: 900px) {
  .code-frag {
    display: block;
  }

  .code-frag-1 {
    top: 7%;
    right: 6%;
  }

  .code-frag-2 {
    top: 30%;
    right: 4%;
  }

  .code-frag-3 {
    bottom: 12%;
    right: 10%;
  }
}

.hero-mark {
  position: absolute;
  z-index: 2;
  /* Sits clear above the headline: the two-line "Software for / everyday."
     reaches further right than the old wording did.
     -70px was a fixed offset against a mark that scales with the viewport, so
     on a 320px screen it cut 70px off a 154px mark: only 38% of the X survived,
     and the crop landed exactly on the sticky header's edge, which reads as
     broken rather than deliberate. Trimmed so the crossing point and most of
     the mass stay on screen, letting the bleed happen off the viewport's right
     edge instead, where a crop looks intentional. */
  top: -24px;
  right: -12%;
  left: auto;
  transform: none;
  /* Capped at 140px so the mark always ends above the headline. At 196px it
     stood 188px tall on a 390px screen and its lower arm ran straight through
     "Software for" — the text stays on top, but a solid black X behind black
     type is not worth reading around. */
  width: min(46vw, 140px);
  pointer-events: none;
}

.hero-mark-img {
  width: 100%;
  height: auto;
  /* No permanent will-change: it would pin a compositor layer for this large
     image for the life of the page. The parallax shift is only 14px. */
}

@media (min-width: 900px) {
  .hero-mark {
    top: 50%;
    right: -6%;
    transform: translateY(-50%);
    width: min(46vw, 620px);
  }
}

.hero-inner {
  position: relative;
  z-index: 3;
  padding-block: var(--space-6) var(--space-3);
}

.hero-content {
  max-width: 560px;
}

.hero h1 {
  /* The floor was 3rem, but at 320px "Software for" measures 283px against a
     272px column, so it broke and left "for" alone on a line. 2.6rem fits with
     room to spare. The curve is otherwise untouched: the floor stops applying
     at ~427px and everything from 533px up is identical to before. */
  font-size: clamp(2.6rem, 6vw + 1rem, 5.25rem);
  font-weight: 800;
  margin-bottom: var(--space-3);
}

.hero-lead {
  font-size: 1.1rem;
  max-width: 44ch;
  color: #33363d;
}

@media (min-width: 900px) {
  .hero-inner {
    padding-block: var(--space-7) calc(var(--space-6) * 1.4);
  }
}

/* ==========================================================================
   Dark 4-column principles strip
   ========================================================================== */
.strip {
  background: var(--ink);
  color: var(--offwhite);
  padding-block: var(--space-4);
}

.strip-grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: 1fr;
}

.strip-grid li {
  padding-top: var(--space-3);
  border-top: 1px solid #23262d;
}

.strip-icon {
  color: var(--teal);
  width: 22px;
  height: 22px;
  margin-bottom: var(--space-2);
}

/* h2 for correct document outline, sized as a card heading rather than a
   section heading. */
.strip-grid h2 {
  color: var(--offwhite);
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 0.4rem;
}

.strip-grid p {
  color: var(--grey-on-dark);
  font-size: 0.92rem;
}

@media (min-width: 760px) {
  .strip-grid {
    grid-template-columns: repeat(4, 1fr);
  }

  .strip-grid li {
    padding-top: 0;
    padding-left: var(--space-3);
    border-top: 0;
    border-left: 1px solid #23262d;
  }

  .strip-grid li:first-child {
    padding-left: 0;
    border-left: 0;
  }
}

/* ==========================================================================
   Products — Made by X
   ========================================================================== */
.products {
  background: var(--ink);
  color: var(--offwhite);
  padding-block: var(--space-6);
  border-top: 1px solid #23262d;
}

.products-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.products-head h2 {
  color: var(--offwhite);
}

.product-cards {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: 1fr;
}

@media (min-width: 860px) {
  .product-cards {
    grid-template-columns: repeat(3, 1fr);
  }
}

.product-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--ink-card);
  border: 1px solid var(--ink-border);
  border-radius: var(--radius-card);
  overflow: hidden;
  transition: border-color 0.25s var(--ease), transform 0.25s var(--ease);
}

.product-card:hover,
.product-card:focus-within {
  border-color: var(--teal);
  transform: translateY(-3px);
}

.product-thumb {
  position: relative;
  height: 182px;
  background: #1a1d23;
  overflow: hidden;
}

.orb {
  position: absolute;
  border-radius: 50%;
}

/* The badge straddles the thumb and the body. It is a child of .product-body,
   not .product-thumb: the thumb clips its overflow to contain the decorative
   artwork, which cut off the badge's lower 18px. Sitting in the body, which
   does not clip, it also paints above the thumb as the later sibling, so the
   whole tile shows. */
.product-icon-badge {
  position: absolute;
  top: -26px;
  left: 20px;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  background: var(--ink);
  border: 1px solid var(--ink-border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--teal);
  overflow: hidden;
}

.product-icon-badge svg {
  width: 20px;
  height: 20px;
}

/* App icon inside a badge tile. The supplied render carries a wide margin of
   empty canvas, so it is scaled up inside the clipped tile to bring the
   artwork to the proportion an icon normally occupies. */
.badge-icon {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.9);
}

.product-body {
  /* Containing block for .product-icon-badge. The generous top padding leaves
     room for the badge to overlap upward without touching the heading. */
  position: relative;
  padding: 34px 20px 22px;
}

.product-body h3 {
  color: var(--offwhite);
  margin-bottom: 0.4rem;
}

.product-body p {
  color: var(--grey-on-dark);
  font-size: 0.92rem;
  margin-bottom: var(--space-2);
}

/* Homepage product card actions. The explore link leads; the waitlist follows
   in a quieter weight and the neutral on-dark grey, so the two do not compete
   for the same glance inside a small card. */
.card-links {
  display: flex;
  flex-wrap: wrap;
  /* Baseline, not centre: the two links are set at different sizes, so
     centring left their text sitting a pixel out of line with each other. */
  align-items: baseline;
  gap: 0.35rem var(--space-3);
}

.card-waitlist {
  display: inline-flex;
  align-items: center;
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--grey-on-dark);
  border-bottom: 1px solid rgba(167, 170, 176, 0.35);
}

.card-waitlist:hover,
.card-waitlist:focus-visible {
  color: var(--offwhite);
  border-bottom-color: var(--offwhite);
}

/* Matches the .text-link touch target it sits beside. */
@media (max-width: 767px) {
  .card-waitlist {
    min-height: 44px;
  }
}

/* ==========================================================================
   Approach + Simple on purpose
   ========================================================================== */
.approach {
  background: var(--offwhite);
  padding-block: var(--space-6);
}

.approach-grid {
  display: grid;
  gap: var(--space-3);
}

.approach-grid h2 {
  max-width: 12ch;
}

.approach-copy p + p {
  margin-top: var(--space-2);
  color: #33363d;
}

@media (min-width: 760px) {
  .approach-grid {
    grid-template-columns: 0.9fr 1fr;
    gap: var(--space-5);
    align-items: start;
  }
}

.purpose {
  padding-top: var(--space-5);
  margin-top: var(--space-5);
  border-top: 1px solid var(--grey-soft);
}

.purpose-list {
  display: grid;
  gap: var(--space-4);
  margin-top: var(--space-3);
}

.purpose-list li {
  padding-top: var(--space-3);
  border-top: 1px solid var(--grey-soft);
}

.purpose-icon {
  color: var(--teal);
  width: 24px;
  height: 24px;
  margin-bottom: var(--space-2);
}

.purpose-list h3 {
  margin-bottom: 0.4rem;
}

.purpose-list p {
  color: var(--grey-text);
  font-size: 0.95rem;
}

@media (min-width: 700px) {
  .purpose-list {
    grid-template-columns: repeat(3, 1fr);
  }

  .purpose-list li {
    padding-top: 0;
    padding-left: var(--space-3);
    border-top: 0;
    border-left: 1px solid var(--grey-soft);
  }

  .purpose-list li:first-child {
    padding-left: 0;
    border-left: 0;
  }
}

/* ==========================================================================
   Brand statement (dark, full-width, faint cropped X)
   ========================================================================== */
.studio {
  background: var(--ink);
  color: var(--offwhite);
  padding-block: var(--space-6);
  position: relative;
  overflow: hidden;
  text-align: center;
}

.studio-watermark {
  position: absolute;
  top: 50%;
  left: 62%;
  width: min(120vw, 1000px);
  transform: translate(-50%, -50%);
  filter: invert(1);
  opacity: 0.05;
  pointer-events: none;
}

.studio-inner {
  position: relative;
  z-index: 2;
}

.studio .eyebrow {
  margin-bottom: var(--space-3);
}

.studio-copy {
  font-size: clamp(1.4rem, 2.2vw + 1rem, 2.25rem);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.3;
  max-width: 20ch;
  margin-inline: auto;
}

.studio-rule {
  display: block;
  width: 44px;
  height: 2px;
  background: var(--teal);
  margin: var(--space-3) auto 0;
}

/* ==========================================================================
   Contact
   ========================================================================== */
.contact {
  background: var(--offwhite);
  padding-block: var(--space-6);
}

.contact-grid {
  display: grid;
  gap: var(--space-3);
}

.contact-heading {
  max-width: 8ch;
}

.contact-note {
  color: var(--grey-text);
}

.contact-note + .contact-note {
  margin-top: 0.35rem;
}

.contact-email {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-size: clamp(1.5rem, 2.2vw + 1rem, 2.25rem);
  font-weight: 700;
  color: var(--teal);
  letter-spacing: -0.01em;
  margin-top: var(--space-3);
}

@media (min-width: 700px) {
  .contact-email {
    margin-top: var(--space-4);
  }
}

/* The primary call to action on the home page, so it should be an easy tap. */
@media (max-width: 767px) {
  .contact-email {
    min-height: 44px;
  }
}

.contact-email span {
  display: inline-block;
  transition: transform 0.2s var(--ease);
}

.contact-email:hover span,
.contact-email:focus-visible span {
  transform: translateX(4px);
}

@media (min-width: 700px) {
  .contact-grid {
    grid-template-columns: 1fr 1fr;
    align-items: start;
    gap: var(--space-5);
  }
}

/* ==========================================================================
   Footer
   ========================================================================== */
.site-footer {
  background: var(--ink);
  color: var(--offwhite);
  padding-block: var(--space-5);
  border-top: 1px solid #23262d;
}

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
}

.footer-brand {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.footer-logo-mark {
  height: 24px;
  width: auto;
  filter: invert(1);
}

.footer-name-group {
  display: flex;
  flex-direction: column;
}

.footer-name {
  font-weight: 700;
  letter-spacing: -0.01em;
}

.footer-tagline {
  color: var(--grey-on-dark);
  font-size: 0.85rem;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  font-size: 0.9rem;
}

@media (min-width: 700px) {
  .footer-links {
    gap: var(--space-4);
  }
}

/* Footer links were 23px tall and sat close together — the easiest place on
   the site to mis-tap. The row gap comes off to absorb the added height, so
   the footer does not grow. */
@media (max-width: 767px) {
  .footer-links {
    gap: 0 var(--space-3);
  }

  .footer-links a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

.footer-email {
  color: var(--teal);
  transition: opacity 0.2s var(--ease);
}

.footer-email:hover,
.footer-email:focus-visible {
  opacity: 0.8;
}

.footer-links a:not(.footer-email) {
  color: #d7d8db;
  transition: color 0.2s var(--ease);
}

.footer-links a:not(.footer-email):hover,
.footer-links a:not(.footer-email):focus-visible {
  color: var(--teal);
}

/* Legal strip: copyright left, operating-company line right. Once there is no
   room for both they wrap and stack, each falling back to the left edge. */
.footer-legal {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.35rem var(--space-3);
  margin-top: var(--space-3);
  border-top: 1px solid #23262d;
  padding-top: var(--space-3);
}

.footer-copyright,
.footer-entity,
.footer-trademark {
  color: #797d84;
  font-size: 0.8rem;
}

/* Google's required attribution for the Play badge, which now appears on nine
   pages. Someone else's trademark rather than X Made's own legal identity, so
   it takes a row of its own beneath the copyright pair instead of turning that
   two-way split into a cramped three-way one.

   The wording is what Google's legal line generator returns for Google Play in
   English at "featured" usage (their term for using the logo). It is their
   text, not ours — regenerate it at
   https://partnermarketinghub.withgoogle.com/tools/legal-line-generator/
   rather than editing it by hand. */
.footer-trademark {
  flex-basis: 100%;
}

/* ==========================================================================
   Simple content pages (privacy / support)
   ========================================================================== */
.page-content {
  padding-block: var(--space-6);
}

.page-content h1 {
  font-size: clamp(2.5rem, 4.5vw + 1rem, 4rem);
  margin-bottom: var(--space-3);
}

/* Long-form vertical rhythm.
   This used to be `p + p` alone, which was enough for the privacy pages: they
   are an h2 followed by consecutive paragraphs, so the adjacency always held.
   The support guides interleave h3, lists and tables, where `p + p` never
   matches — and with the global `* { margin: 0 }` that left every subheading
   sitting flush against the paragraph above it. Spacing is declared on the
   elements themselves now, so it survives any order of content.
   The colour moves here for the same reason: on `p + p` it painted the first
   paragraph of each group darker than the rest, which read as an accident once
   a page had many single-paragraph sections. */
.page-content p {
  margin-bottom: var(--space-2);
  color: #33363d;
}

.page-content p + p {
  margin-top: var(--space-2);
}

.page-content h3 {
  margin-top: var(--space-3);
  margin-bottom: 0.45rem;
  /* The shared h1/h2/h3 rule sets 1.07, which is for display sizes. At
     subheading size a wrapped line needs room. */
  line-height: 1.3;
}

/* A heading introduces what follows it, so the gap beneath stays tighter than
   the gap above. */
.page-content h2 + p,
.page-content h3 + p {
  margin-top: 0;
}

/* ==========================================================================
   Contact page
   Everything below is scoped to .page-contact so no other page is affected.
   ========================================================================== */

/* ---- Dark header (contact page only) ---- */
.page-dark-nav .site-header {
  background: var(--ink);
  border-bottom-color: transparent;
}

.page-dark-nav .site-header.is-scrolled {
  border-bottom-color: #23262d;
}

/* Logo artwork is black; invert it against the dark bar. */
.page-dark-nav .logo-mark {
  filter: invert(1);
}

.page-dark-nav .logo-word,
.page-dark-nav .primary-nav a {
  color: var(--offwhite);
}

.page-dark-nav .nav-toggle-bar {
  background: var(--offwhite);
}

.page-dark-nav .primary-nav a[aria-current="page"] {
  color: var(--teal);
}

@media (max-width: 767px) {
  .page-dark-nav .primary-nav {
    background: var(--ink);
    border-bottom-color: #23262d;
  }
}

/* ---- Hero ---- */
.contact-hero {
  position: relative;
  background: var(--offwhite);
  overflow: hidden;
  padding-block: var(--space-6) var(--space-5);
}

.contact-hero-inner {
  position: relative;
  z-index: 2;
}

.contact-atmos {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

/* Pale teal wash, top-right. Deliberately faint. */

@media (max-width: 767px) {
  .atmos-glow {
    width: 340px;
    height: 340px;
    top: -140px;
    right: -120px;
  }
  .atmos-dots {
    width: 150px;
    height: 120px;
    top: 24px;
    right: 12px;
    opacity: 0.5;
  }
}

/* Shares the inner-page hero scale used by the apps and about heroes. */
.contact-hero h1 {
  font-size: clamp(2.25rem, 4vw + 1rem, 3.6rem);
  font-weight: 800;
  margin-bottom: var(--space-3);
}

.contact-intro {
  color: #4a4d54;
  font-size: 1.05rem;
  line-height: 1.7;
  max-width: 44ch;
  margin-bottom: var(--space-5);
}

/* ---- Trust row ---- */
.trust-row {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: 1fr;
}

.trust-item {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
}

.trust-icon {
  flex-shrink: 0;
  width: 42px;
  height: 42px;
  border-radius: 10px;
  background: rgba(15, 107, 109, 0.08);
  color: var(--teal);
  display: flex;
  align-items: center;
  justify-content: center;
}

.trust-icon svg {
  width: 20px;
  height: 20px;
}

.trust-item h2 {
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.3;
  margin-bottom: 0.2rem;
}

.trust-item p {
  font-size: 0.88rem;
  color: var(--grey-text);
  line-height: 1.5;
  max-width: 24ch;
}

@media (min-width: 640px) {
  .trust-row {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-4);
  }
}

/* ---- Form + aside layout ---- */
.contact-main {
  background: var(--offwhite);
  padding-bottom: var(--space-6);
}

/* Page-scoped: the homepage "Say hello" section uses .contact-grid too, and
   these rules would otherwise override its balanced 1fr/1fr columns. */
.page-contact .contact-grid {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: 1fr;
  align-items: start;
}

@media (min-width: 940px) {
  .page-contact .contact-grid {
    grid-template-columns: 1.55fr 1fr;
    gap: var(--space-4);
  }
}

/* ---- Form panel ---- */
.contact-panel {
  background: var(--white);
  border: 1px solid var(--grey-soft);
  border-radius: 12px;
  padding: var(--space-3);
  box-shadow: 0 1px 2px rgba(17, 19, 24, 0.03);
}

@media (min-width: 640px) {
  .contact-panel {
    padding: var(--space-5);
  }
}

/* Reset the earlier max-width now the panel controls the measure. */
.contact-form {
  max-width: none;
}

.form-note-icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  color: var(--grey-mid);
}

.page-contact .form-note {
  display: flex;
  align-items: center;
  gap: 0.45rem;
}

/* ---- Aside ---- */
.contact-aside {
  background: rgba(15, 107, 109, 0.045);
  border: 1px solid rgba(15, 107, 109, 0.1);
  border-radius: 12px;
  padding: var(--space-3);
}

@media (min-width: 640px) {
  .contact-aside {
    padding: var(--space-4);
  }
}

.aside-item + .aside-item {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid rgba(15, 107, 109, 0.12);
}

.aside-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 10px;
  background: rgba(15, 107, 109, 0.1);
  color: var(--teal);
  margin-bottom: var(--space-2);
}

.aside-icon svg {
  width: 20px;
  height: 20px;
}

.aside-item h2 {
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 0.35rem;
}

.aside-item p {
  font-size: 0.92rem;
  color: #4a4d54;
  line-height: 1.6;
}

/* Legal identity: present for the record, quieter than the aside copy. */
.aside-item .aside-legal {
  margin-top: 0.55rem;
  font-size: 0.82rem;
  color: var(--grey-text);
}

.aside-email {
  color: var(--teal);
  font-weight: 600;
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s var(--ease);
}

.aside-email:hover,
.aside-email:focus-visible {
  border-bottom-color: var(--teal);
}

@media (max-width: 767px) {
  .aside-email {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

.form-field {
  margin-bottom: var(--space-3);
}

.form-field label {
  display: block;
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

.label-optional {
  font-weight: 400;
  color: var(--grey-text);
}

.form-field input,
.form-field select,
.form-field textarea {
  width: 100%;
  font: inherit;
  font-size: 1rem;
  color: var(--ink);
  background: var(--white);
  border: 1px solid var(--grey-soft);
  border-radius: var(--radius);
  padding: 0.8rem 0.9rem;
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}

.form-field textarea {
  min-height: 170px;
  resize: vertical;
  line-height: 1.6;
}

.form-field select {
  appearance: none;
  /* Chevron drawn inline so no icon font or image request is needed. */
  background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%238b8e93' stroke-width='1.5'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.9rem center;
  background-size: 12px 8px;
  padding-right: 2.4rem;
}

.form-field input:hover,
.form-field select:hover,
.form-field textarea:hover {
  border-color: var(--grey-mid);
}

.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
  outline: none;
  border-color: var(--teal);
  box-shadow: 0 0 0 3px rgba(15, 107, 109, 0.14);
}

/* Keep a visible ring for keyboard users even where focus styling is custom. */
.form-field input:focus-visible,
.form-field select:focus-visible,
.form-field textarea:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
}

.form-field [aria-invalid="true"] {
  border-color: #a3341f;
}

.form-error {
  margin-top: 0.45rem;
  font-size: 0.875rem;
  color: #a3341f;
}

.form-alert {
  border-left: 2px solid #a3341f;
  background: var(--offwhite);
  padding: var(--space-2) var(--space-3);
  margin-bottom: var(--space-4);
  font-size: 0.95rem;
}

.form-alert:focus {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
}

/* Waitlist confirmation. The accent rule distinguishes it from .form-alert,
   which carries the same shape in the error colour directly above it. */
.form-waitlist-note {
  border-left: 2px solid var(--teal);
  background: rgba(15, 107, 109, 0.05);
  padding: var(--space-2) var(--space-3);
  margin-bottom: var(--space-4);
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--ink);
}

/* App context, for someone who followed an app's own support link. A quiet
   pill rather than a panel: it confirms which product the enquiry will be
   filed against without competing with the fields under it, and borrows the
   button radius so it reads as part of the same family.

   The `hidden` rule is not redundant. `display: inline-block` in a class sits
   above the UA stylesheet's [hidden] { display: none }, so without it the
   empty pill would show on every generic enquiry. Same collision, and the
   same fix, as the launch-price attributes further down this file. */
.form-app-note {
  display: inline-block;
  margin-bottom: var(--space-4);
  padding: 0.3rem 0.7rem;
  border: 1px solid rgba(15, 107, 109, 0.22);
  border-radius: 999px;
  background: rgba(15, 107, 109, 0.06);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--teal);
}

.form-app-note[hidden] {
  display: none;
}

/* Honeypot: off-screen rather than display:none, which bots skip. */
.form-website {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-submit {
  margin-top: var(--space-2);
  cursor: pointer;
}

.form-submit[disabled] {
  opacity: 0.6;
  cursor: default;
}

.form-note {
  margin-top: var(--space-3);
  font-size: 0.85rem;
  color: var(--grey-text);
}

.form-note a {
  color: var(--teal);
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s var(--ease);
}

.form-note a:hover,
.form-note a:focus-visible {
  border-bottom-color: var(--teal);
}

/* ---- Success state ---- */
.form-success {
  border-top: 2px solid var(--teal);
  padding-top: var(--space-4);
  max-width: 46ch;
}

.form-success h1 {
  margin-bottom: var(--space-2);
}

.form-success p {
  color: #33363d;
}

.form-success-back {
  margin-top: var(--space-4);
}

/* ==========================================================================
   Support page
   Scoped to .page-support so no other page is affected.
   ========================================================================== */

/* ---- Hero ---- */
.support-hero {
  position: relative;
  background: var(--offwhite);
  overflow: hidden;
  padding-block: var(--space-6) var(--space-5);
}

.support-hero-inner {
  position: relative;
  z-index: 2;
}

.support-atmos {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

@media (max-width: 767px) {
  .page-support .atmos-glow {
    width: 320px;
    height: 320px;
    top: -130px;
    right: -110px;
  }
  .page-support .atmos-dots {
    width: 160px;
    height: 200px;
    opacity: 0.45;
  }
}

/* Shares the inner-page hero scale used by the apps and about heroes. */
.support-hero h1 {
  font-size: clamp(2.25rem, 4vw + 1rem, 3.6rem);
  font-weight: 800;
  margin-bottom: var(--space-3);
}

.support-intro {
  color: #4a4d54;
  font-size: 1.05rem;
  line-height: 1.7;
  max-width: 42ch;
  margin-bottom: var(--space-4);
}

/* ---- Search (visual placeholder) ---- */

/* ---- Quick links ---- */

@media (max-width: 559px) {
  .quick-links {
    flex-direction: column;
    gap: var(--space-2);
  }
}

/* ---- Popular topics ---- */
.support-topics {
  background: var(--offwhite);
  padding-bottom: var(--space-5);
}

.topics-heading {
  font-size: 1.5rem;
  margin-bottom: var(--space-3);
}

@media (min-width: 620px) {
  .topic-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 940px) {
  .topic-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-3);
  }
}

/* ---- Still need help ---- */
.support-help {
  background: var(--offwhite);
  padding-bottom: var(--space-6);
}

.help-panel {
  background: rgba(15, 107, 109, 0.05);
  border: 1px solid rgba(15, 107, 109, 0.1);
  border-radius: 14px;
  padding: var(--space-3);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

@media (min-width: 640px) {
  .help-panel {
    padding: var(--space-5);
  }
}

@media (min-width: 760px) {
  .help-panel {
    grid-template-columns: 1fr 1fr;
  }
}

@media (min-width: 1000px) {
  .help-panel {
    grid-template-columns: 1.5fr 1fr 1fr;
    gap: var(--space-5);
    align-items: start;
  }
}

.help-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 68px;
  height: 68px;
  border-radius: 50%;
  background: rgba(15, 107, 109, 0.1);
  color: var(--teal);
  margin-bottom: var(--space-3);
}

.help-icon svg {
  width: 28px;
  height: 28px;
}

.help-primary h2 {
  font-size: 1.6rem;
  margin-bottom: 0.6rem;
}

.help-primary p {
  color: #4a4d54;
  font-size: 0.95rem;
  max-width: 32ch;
  margin-bottom: var(--space-3);
}

.help-item-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  background: rgba(15, 107, 109, 0.1);
  color: var(--teal);
  margin-bottom: var(--space-2);
}

.help-item-icon svg {
  width: 20px;
  height: 20px;
}

.help-item h3 {
  font-size: 1rem;
  margin-bottom: 0.4rem;
}

.help-email {
  color: var(--teal);
  font-weight: 600;
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s var(--ease);
}

.help-email:hover,
.help-email:focus-visible {
  border-bottom-color: var(--teal);
}

@media (max-width: 767px) {
  .help-email {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

.help-note {
  font-size: 0.9rem;
  line-height: 1.55;
  color: #4a4d54;
  margin-top: 0.5rem;
}

/* Thin separators between the three panel areas on wide screens. */
@media (min-width: 1000px) {
  .help-item {
    padding-left: var(--space-5);
    border-left: 1px solid rgba(15, 107, 109, 0.14);
  }
}

/* ==========================================================================
   About page
   Scoped to .page-about so no other page is affected.
   ========================================================================== */

/* ---- Hero ---- */
.about-hero {
  position: relative;
  background: var(--offwhite);
  overflow: hidden;
  padding-block: var(--space-6) var(--space-5);
}

.about-hero-inner {
  position: relative;
  z-index: 2;
}

.about-atmos {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

.about-hero h1 {
  font-size: clamp(2.25rem, 4vw + 1rem, 3.6rem);
  font-weight: 800;
  margin-bottom: var(--space-3);
  max-width: 16ch;
}

.about-lead {
  color: #4a4d54;
  font-size: 1.05rem;
  line-height: 1.7;
  max-width: 52ch;
}

.about-lead + .about-lead {
  margin-top: var(--space-2);
}

.about-location {
  display: flex;
  align-items: flex-start;
  gap: 0.9rem;
  margin-top: var(--space-4);
}

.about-location-icon {
  flex-shrink: 0;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: rgba(15, 107, 109, 0.08);
  color: var(--teal);
  display: flex;
  align-items: center;
  justify-content: center;
}

.about-location-icon svg {
  width: 21px;
  height: 21px;
}

.about-location h2 {
  font-size: 0.98rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.3;
  margin-bottom: 0.15rem;
}

.about-location p {
  font-size: 0.9rem;
  color: var(--grey-text);
}

/* ---- Values row ---- */
.about-values {
  background: var(--offwhite);
  padding-bottom: var(--space-5);
}

.values-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
}

.values-row li {
  padding-top: var(--space-3);
  border-top: 1px solid var(--grey-soft);
}

.value-icon {
  display: block;
  color: var(--teal);
  margin-bottom: var(--space-2);
}

.value-icon svg {
  width: 27px;
  height: 27px;
}

.values-row h2 {
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 0.35rem;
}

.values-row p {
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--grey-text);
  max-width: 26ch;
}

@media (min-width: 620px) {
  .values-row {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-4) var(--space-3);
  }
}

@media (min-width: 940px) {
  .values-row {
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-4);
  }

  /* Vertical dividers only once the row is genuinely a row. */
  .values-row li {
    padding-top: 0;
    padding-left: var(--space-3);
    border-top: 0;
    border-left: 1px solid var(--grey-soft);
  }

  .values-row li:first-child {
    padding-left: 0;
    border-left: 0;
  }
}

/* ---- Mission ---- */
.about-mission {
  background: var(--offwhite);
  padding-bottom: var(--space-5);
}

.mission-panel {
  background: rgba(15, 107, 109, 0.05);
  border: 1px solid rgba(15, 107, 109, 0.1);
  border-radius: 14px;
  padding: var(--space-3);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  align-items: center;
}

@media (min-width: 640px) {
  .mission-panel {
    padding: var(--space-5);
  }
}

@media (min-width: 940px) {
  .mission-panel {
    grid-template-columns: 1fr 1.15fr;
    gap: var(--space-5);
  }
}

.mission-copy h2 {
  font-size: 1.6rem;
  margin-bottom: var(--space-2);
}

.mission-copy p {
  color: #4a4d54;
  font-size: 0.98rem;
  line-height: 1.7;
  max-width: 44ch;
}

.mission-copy p + p {
  margin-top: var(--space-2);
}

.mission-art {
  color: var(--grey-mid);
  opacity: 0.85;
}

.mission-art svg {
  width: 100%;
  height: auto;
}

/* Device screens read as X Made surfaces. */

/* Copy above illustration on small screens, per the mobile spec. */
@media (max-width: 619px) {
  .mission-art {
    display: none;
  }
}

/* ---- Team ---- */
.about-team {
  background: var(--offwhite);
  padding-bottom: var(--space-6);
}

.team-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  align-items: start;
}

@media (min-width: 800px) {
  .team-grid {
    grid-template-columns: 1fr 1.6fr;
    gap: var(--space-5);
  }
}

.team-intro h2 {
  font-size: 1.6rem;
  margin-bottom: var(--space-2);
}

.team-intro p {
  color: var(--grey-text);
  font-size: 0.95rem;
  line-height: 1.6;
  max-width: 30ch;
}

.team-card {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  background: var(--white);
  border: 1px solid var(--grey-soft);
  border-radius: 12px;
  padding: var(--space-3);
  box-shadow: 0 1px 2px rgba(17, 19, 24, 0.03);
}

@media (min-width: 640px) {
  .team-card {
    padding: var(--space-4);
    gap: var(--space-4);
  }
}

/* Neutral, non-photographic stand-in until a real approved photo exists. */
.team-avatar {
  flex-shrink: 0;
  width: 84px;
  height: 84px;
  border-radius: 50%;
  background: rgba(15, 107, 109, 0.08);
  border: 1px solid rgba(15, 107, 109, 0.14);
  color: var(--teal);
  font-size: 1.4rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  display: flex;
  align-items: center;
  justify-content: center;
}

.team-photo {
  flex-shrink: 0;
  width: 84px;
  height: 84px;
  border-radius: 50%;
  object-fit: cover;
}

.team-details h3 {
  font-size: 1.1rem;
  margin-bottom: 0.2rem;
}

.team-role {
  color: var(--teal);
  font-size: 0.92rem;
  font-weight: 600;
  margin-bottom: 0.4rem;
}

.team-bio {
  font-size: 0.92rem;
  line-height: 1.6;
  color: #4a4d54;
  max-width: 34ch;
}

/* ==========================================================================
   Apps page
   Scoped to .page-apps. The phone/app visuals are CSS representations of the
   interfaces, not screenshots — all marked aria-hidden.
   ========================================================================== */

/* ---- Shared line-art helpers ---- */

/* ---- Hero ---- */
.apps-hero {
  position: relative;
  background: var(--offwhite);
  overflow: hidden;
  padding-block: var(--space-6) var(--space-5);
}

.apps-hero-inner {
  position: relative;
  z-index: 2;
}

@media (max-width: 899px) {
  /* Kept above the headline so decoration never sits behind body text. */
  .apps-hero-art {
    top: 0;
    right: -14%;
    transform: none;
    width: 170px;
    opacity: 0.28;
  }
  .apps-hero-symbol {
    display: none;
  }
}

.apps-hero h1 {
  font-size: clamp(2.25rem, 4vw + 1rem, 3.6rem);
  font-weight: 800;
  margin-bottom: var(--space-3);
}

.apps-lead {
  color: #4a4d54;
  font-size: 1.05rem;
  line-height: 1.7;
  max-width: 46ch;
}

/* ---- Section heading with rules ---- */
.apps-showcase {
  background: var(--offwhite);
  padding-bottom: var(--space-5);
}

.apps-rule-heading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  font-size: clamp(1.5rem, 1.6vw + 1rem, 1.9rem);
  margin-bottom: var(--space-4);
  text-align: center;
}

/* The label must not be the thing that gives way. Without this it shrank to
   min-content at 320px and broke into "Our / Apps" with a rule either side. */
.apps-rule-heading > span:not(.apps-rule) {
  flex: 0 0 auto;
  white-space: nowrap;
}

.apps-rule {
  flex: 0 1 90px;
  min-width: 0;
  height: 4px;
  background-image: radial-gradient(circle, var(--teal) 1.2px, transparent 1.6px);
  background-size: 11px 4px;
  opacity: 0.55;
}

/* ---- App cards ---- */
.app-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  align-items: stretch;
}

/* Two cards side by side only once each card is wide enough to hold a
   readable text column next to a phone. Below this they stack full-width. */
@media (min-width: 1200px) {
  .app-grid {
    grid-template-columns: 1fr 1.1fr;
  }
}

.app-card {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  background: var(--white);
  border: 1px solid var(--grey-soft);
  border-radius: 14px;
  padding: var(--space-3);
  box-shadow: 0 1px 2px rgba(17, 19, 24, 0.03);
}

/* Info beside the phone only when there is room for both; a 560px card
   left the description wrapping to single words. */
@media (min-width: 760px) {
  .app-card {
    grid-template-columns: minmax(240px, 1fr) auto;
    gap: var(--space-4);
    padding: var(--space-4);
    align-items: center;
  }
}

.app-badge {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 62px;
  height: 62px;
  border-radius: 15px;
  font-size: 1.7rem;
  font-weight: 600;
  margin-bottom: var(--space-2);
  overflow: hidden;
}

.app-badge-sumx {
  background: #14161b;
  color: #35d0c0;
}

.app-badge-clox {
  background: #1b1533;
  color: #b58cf6;
  font-family: var(--font-mono);
  font-size: 1.3rem;
}

.app-info h3 {
  font-size: 1.9rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-bottom: 0.2rem;
}

.app-tagline {
  color: var(--teal);
  font-weight: 600;
  font-size: 1rem;
  margin-bottom: var(--space-2);
}

.app-desc {
  color: #4a4d54;
  font-size: 0.92rem;
  line-height: 1.65;
  max-width: 34ch;
  margin-bottom: var(--space-3);
}

.app-features li {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  font-size: 0.9rem;
  color: #33363d;
}

.app-features li + li {
  margin-top: 0.65rem;
}

.tick {
  flex-shrink: 0;
  color: var(--teal);
  margin-top: 1px;
}

.tick svg {
  width: 17px;
  height: 17px;
}

/* ---- Phone shell ---- */
.app-visual {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

/* Both cards get an identical visual column, so the phones land in exactly
   the same place regardless of what sits beneath them (theme toggle vs
   swatch row). Without this the wider swatch row pushed CLOX 18px left. */
@media (min-width: 760px) {
  .app-visual {
    width: 244px;
    flex-shrink: 0;
    /* Top-aligned rather than centred: the swatch row is taller than the
       theme toggle, which otherwise floated the CLOX phone 10px higher. */
    align-self: start;
  }
}

.phone {
  position: relative;
  flex-shrink: 0;
  width: 208px;
  border-radius: 30px;
  background: #0b0d11;
  border: 1px solid #2a2e36;
  padding: 8px;
  box-shadow: 0 10px 26px rgba(17, 19, 24, 0.16);
}

.phone-island {
  position: absolute;
  top: 15px;
  left: 50%;
  transform: translateX(-50%);
  width: 62px;
  height: 15px;
  border-radius: 999px;
  background: #000;
  z-index: 3;
}

.phone-screen {
  position: relative;
  border-radius: 23px;
  overflow: hidden;
  /* Fixed, not min-height, so every app screen is exactly the same size. */
  height: 410px;
  display: flex;
  flex-direction: column;
  font-size: 11px;
}

.phone-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 9px 14px 4px;
  font-size: 9px;
  font-weight: 600;
  color: #f2f3f5;
}

.status-icons {
  display: inline-flex;
  align-items: flex-end;
  gap: 2px;
}

.status-icons i {
  display: block;
  width: 3px;
  background: #f2f3f5;
  border-radius: 1px;
}

.status-icons i:nth-child(1) { height: 4px; }
.status-icons i:nth-child(2) { height: 6px; }
.status-icons i:nth-child(3) { height: 8px; }

/* ---- Device frame: real product screenshots -----------------------------
   Wraps an exported 1080x2400 capture in a thin Android-style frame. The
   .phone rules above draw a fake interface; these show the real one, so the
   frame is deliberately quieter: one hairline bezel, one soft shadow, no
   glare, no perspective, no 3D. The screenshot is the subject.

   No .phone-island here. The captures already contain the device's own
   status bar and gesture pill, so drawing a notch over them would put two
   status bars on one screen.

   The frame stays graphite in both themes because real phone bezels are, and
   because it keeps light-theme captures from bleeding into a light page. */
.device {
  position: relative;
  width: 100%;
  max-width: 240px;
  margin-inline: auto;
  padding: 6px;
  border-radius: 30px;
  background: #0b0d11;
  border: 1px solid #2a2e36;
  box-shadow: 0 10px 26px rgba(17, 19, 24, 0.16);
}

.device img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 24px;
  /* Reserves the box before the PNG decodes, so a screenshot arriving late
     never shifts the copy beside it. Matches the 1080x2400 capture ratio. */
  aspect-ratio: 1080 / 2400;
  /* Shows through for the moment before decode, and behind the corner radius
     where the capture's own square corners are clipped away. */
  background: #16181d;
}

/* The hero screenshot carries the page, so it runs larger than the supporting
   ones. Both stay under .app-visual's 244px column on the Apps page. */
.device--hero {
  max-width: 268px;
}

@media (min-width: 900px) {
  .device--hero {
    max-width: 300px;
  }
}

/* On a dark band the 16% ink shadow is invisible and the bezel merges with
   the ground, so the frame needs a lighter edge and a deeper shadow to read
   as an object sitting on the section rather than a hole cut into it. */
.product-section--dark .device,
.strip .device {
  border-color: #3a3f48;
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.45);
}

/* ---- Screenshot rows ----
   One to three framed captures with a caption under each. Wraps to a single
   column on narrow screens without a breakpoint: the flex items keep their
   max-width and the row centres what fits. */
.screen-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: flex-start;
  gap: var(--space-4);
  margin: 0 0 var(--space-5);
  padding: 0;
  list-style: none;
}

.screen-row li {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  width: 240px;
  max-width: 100%;
}

/* Sits under a screenshot to say what the screen is. Without it a reader
   meeting the capture out of context has to infer the screen from the copy
   several paragraphs away. */
.screen-caption {
  margin: 0;
  max-width: 30ch;
  color: var(--grey-text);
  font-size: 0.88rem;
  line-height: 1.55;
  text-align: center;
}

.product-section--dark .screen-caption {
  color: var(--grey-on-dark);
}

/* A single centred screenshot between a section intro and the content below
   it. Narrower bottom margin than .screen-row: nothing sits beside it. */
.section-figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-5);
}

/* ---- Device placements ----
   Apps-page hero. The offset pair is composed at .phone's 208px width, so the
   real device has to match that exactly or both the overlap and the crop at
   the right edge shift. */
.apps-hero-products .device {
  width: 208px;
  max-width: none;
  margin-inline: 0;
  flex-shrink: 0;
}

.apps-hero-products .device--back {
  transform: translateY(-14px) rotate(-3deg);
  opacity: 0.55;
}

/* Homepage product card. The thumb is 182px tall and clips its overflow, so
   the device is deliberately sized past it and anchored to the top: the
   status bar, the wordmark and the result stay inside the frame while the
   keypad runs off the bottom edge. Sizing a whole phone to fit would render
   it about 80px wide, which reads as a grey sliver rather than an app. */
.product-thumb--shot {
  display: flex;
  justify-content: center;
}

.device--peek {
  width: 210px;
  max-width: none;
  margin: 26px 0 0;
  /* Only the top corners are ever in view. Leaving the full radius on would
     round two corners that sit below the crop, and the bezel would close
     across the bottom of a phone that is meant to continue. */
  border-radius: 30px 30px 0 0;
  border-bottom: 0;
  padding-bottom: 0;
  box-shadow: 0 -2px 20px rgba(0, 0, 0, 0.3);
}

.device--peek img {
  border-radius: 24px 24px 0 0;
}

/* ---- Theme toggle (decorative) ---- */
.theme-toggle {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--grey-soft);
  border-radius: 999px;
  background: var(--white);
}

.tt-opt {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.45rem 0.95rem;
  border-radius: 999px;
  font-size: 0.83rem;
  font-weight: 600;
  color: var(--grey-mid);
}

.tt-opt svg {
  width: 15px;
  height: 15px;
}

.tt-opt.is-on {
  background: var(--ink);
  color: var(--offwhite);
}

/* ---- CLOX screens ---- */
.clox-phones {
  display: flex;
  gap: var(--space-2);
  max-width: 100%;
  overflow-x: auto;
  padding-bottom: 4px;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}

.clox-phones .phone {
  scroll-snap-align: center;
}

.clox-screen {
  background: #0f1116;
  color: #e6e8eb;
}

.clox-bar,
.clox-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 7px 12px;
  font-size: 8px;
  color: #6f747d;
}

.clox-bar {
  border-bottom: 1px solid #21242b;
}

.cx-title {
  font-family: var(--font-mono);
  font-size: 8px;
  font-weight: 600;
  letter-spacing: 0.18em;
  color: #9aa0a8;
}

.clox-foot {
  margin-top: auto;
  border-top: 1px solid #21242b;
}

.cx-lang {
  font-family: var(--font-mono);
  font-size: 7.5px;
  padding: 3px 7px;
  border-radius: 999px;
  background: #191c22;
  color: #8b919a;
}

.clox-code {
  flex: 1;
  margin: 0;
  padding: 12px;
  font-family: var(--font-mono);
  font-size: 9.5px;
  line-height: 1.75;
  white-space: pre;
  overflow: hidden;
}

/* Syntax colours live only inside the app visuals, never in the site UI. */
.c-key  { color: #c792ea; }
.c-var  { color: #82aaff; }
.c-op   { color: #89ddff; }
.c-prop { color: #f78c6c; }
.c-num  { color: #f7c66b; }
.c-str  { color: #86e1a0; }

/* ---- Theme swatches ---- */
.clox-themes {
  width: 100%;
  text-align: center;
}

.themes-label {
  display: block;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--grey-text);
  margin-bottom: 0.5rem;
}

.swatch-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
}

.swatch {
  width: 44px;
  height: 36px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 600;
  border: 1px solid rgba(255, 255, 255, 0.08);
}

.sw-1 { background: #14202b; color: #7fd6c8; }
.sw-2 { background: #171a2b; color: #8ea6ff; }
.sw-3 { background: #12211a; color: #8ce09f; }
.sw-4 { background: #241a12; color: #f0a35e; }
.sw-5 { background: var(--white); color: #5b6068; border-color: var(--grey-soft); }

/* ---- Principles strip ---- */
.apps-principles {
  background: var(--offwhite);
  padding-bottom: var(--space-4);
}

.principles-strip {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  background: var(--white);
  border: 1px solid var(--grey-soft);
  border-radius: 14px;
  padding: var(--space-3);
}

/* Grid, not a flex row. As siblings of the icon the heading and paragraph were
   both flex items, so at the four-column breakpoint each heading was squeezed
   to 41-73px and broke into three lines ("Made / with / care"). The areas put
   the icon beside a stacked title and body, matching .trust-item. */
.principles-strip li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas:
    "icon title"
    "icon body";
  column-gap: 0.85rem;
  align-items: start;
  padding-top: var(--space-3);
  border-top: 1px solid var(--grey-soft);
}

.principles-strip li:first-child {
  padding-top: 0;
  border-top: 0;
}

.pr-icon {
  grid-area: icon;
  color: var(--teal);
}

.pr-icon svg {
  width: 30px;
  height: 30px;
}

.principles-strip h2 {
  grid-area: title;
  font-size: 0.96rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 0.25rem;
}

.principles-strip p {
  grid-area: body;
  font-size: 0.85rem;
  line-height: 1.6;
  color: var(--grey-text);
}

@media (min-width: 620px) {
  .principles-strip {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-4) var(--space-3);
    padding: var(--space-4);
  }
  .principles-strip li:nth-child(-n + 2) {
    padding-top: 0;
    border-top: 0;
  }
}

@media (min-width: 1000px) {
  .principles-strip {
    grid-template-columns: repeat(4, 1fr);
  }
  .principles-strip li {
    padding-top: 0;
    padding-left: var(--space-3);
    border-top: 0;
    border-left: 1px solid var(--grey-soft);
  }
  .principles-strip li:first-child {
    padding-left: 0;
    border-left: 0;
  }
}

/* ---- More apps panel ---- */
.apps-more {
  background: var(--offwhite);
  padding-bottom: var(--space-6);
}

.more-panel {
  position: relative;
  overflow: hidden;
  background: rgba(15, 107, 109, 0.045);
  border: 1px solid rgba(15, 107, 109, 0.1);
  border-radius: 14px;
  padding: var(--space-3);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  align-items: center;
}

@media (min-width: 640px) {
  .more-panel {
    padding: var(--space-4) var(--space-5);
  }
}

@media (min-width: 860px) {
  .more-panel {
    grid-template-columns: 1.1fr 1fr;
    gap: var(--space-4);
  }
}

.more-copy {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}

.more-icon {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 66px;
  height: 66px;
  border-radius: 50%;
  border: 1px solid rgba(15, 107, 109, 0.3);
  color: var(--teal);
}

.more-icon svg {
  width: 28px;
  height: 28px;
}

.more-copy h2 {
  font-size: 1.5rem;
  margin-bottom: 0.4rem;
}

.more-copy p {
  color: #4a4d54;
  font-size: 0.95rem;
  line-height: 1.6;
  max-width: 40ch;
  margin-bottom: var(--space-2);
}

.more-art {
  color: var(--grey-mid);
  opacity: 0.5;
}

.more-art svg {
  width: 100%;
  height: auto;
}

@media (max-width: 639px) {
  .more-art {
    display: none;
  }
}

/* Declared last so it wins over the base .phone / .clox-code sizes.
   The CLOX code must stay legible on small screens; the phone row scrolls
   horizontally, so the phones get more room rather than being shrunk. */
@media (max-width: 559px) {
  .phone {
    width: 236px;
  }

  .phone-screen {
    height: 460px;
  }

  .clox-code {
    font-size: 11px;
    padding: 13px;
  }

  .sb-code pre {
    font-size: 8px;
  }
}

/* ==========================================================================
   Shared brand components (used across internal pages)
   ========================================================================== */

/* ---- Cropped brush-X hero artwork --------------------------------------
   One strong X moment per page. Oversized, cropped at the viewport edge and
   held at very low opacity so it reads as a brand form, never as decoration
   competing with the copy. Sits behind content and is inert to pointers. */
.hero-x {
  position: absolute;
  top: 50%;
  right: -8%;
  transform: translateY(-50%);
  width: min(44vw, 560px);
  z-index: 1;
  pointer-events: none;
  opacity: 0.06;
}

.hero-x img {
  width: 100%;
  height: auto;
}

/* Slightly stronger on the dark statement bands, which swallow low opacity. */
.hero-x--dark {
  opacity: 0.05;
  filter: invert(1);
}

@media (max-width: 899px) {
  /* Pulled clear above the headline; never sits behind text on small screens. */
  /* Sits in the band above the headline. Kept fully clear of the text rather
     than relying on low opacity to disguise an overlap. */
  .hero-x {
    top: -54px;
    right: -18%;
    transform: none;
    width: 168px;
    opacity: 0.07;
  }
}

/* ---- Outlined / constructed X ------------------------------------------
   A drawn X used where the brush mark would be too heavy: "more coming"
   states and progression moments. Monochrome with a single teal accent. */
.x-construct {
  color: var(--grey-mid);
}

.x-construct svg {
  width: 100%;
  height: auto;
}

.x-construct .xc-solid { opacity: 0.9; }
.x-construct .xc-ghost { opacity: 0.35; }
.x-construct .xc-grid  { opacity: 0.22; }
.x-construct .xc-teal  { color: var(--teal); opacity: 0.8; }

/* ==========================================================================
   Refinement pass — page-specific additions
   ========================================================================== */

/* ---- Apps hero: real product visuals, cropped at the right edge ---- */
.apps-hero-products {
  position: absolute;
  top: 50%;
  right: -4%;
  transform: translateY(-50%) scale(0.82);
  transform-origin: right center;
  display: flex;
  align-items: center;
  z-index: 1;
  pointer-events: none;
}

.apps-hero-products .phone-back {
  transform: translateY(-14px) rotate(-3deg);
  opacity: 0.55;
}

.apps-hero-products .phone-front {
  margin-left: -74px;
  transform: translateY(14px) rotate(2deg);
  box-shadow: 0 18px 44px rgba(17, 19, 24, 0.22);
}

/* Below the two-column breakpoint the products would crowd the copy, so the
   hero falls back to the shared cropped-X treatment instead. */
@media (max-width: 1099px) {
  .apps-hero-products {
    display: none;
  }
}

/* ---- Homepage product card miniatures ---- */
.mini {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.mini-label {
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  color: #8f949c;
  padding: 14px 16px 0;
}

.mini-clox {
  background: #0f1116;
}

.mini-code {
  margin: 0;
  padding: 8px 16px 16px;
  font-family: var(--font-mono);
  font-size: 10px;
  line-height: 1.7;
  white-space: pre;
}

.mini-next {
  background: #14161b;
  align-items: center;
  justify-content: center;
  padding: 14px;
  color: #6f747d;
}

.mini-next svg {
  width: 100%;
  height: auto;
  max-height: 100%;
}

/* Slightly brighter construction marks against the dark card. */
.mini-next .xc-solid { opacity: 0.75; }
.mini-next .xc-ghost { opacity: 0.28; }
.mini-next .xc-grid  { opacity: 0.16; }

/* ---- Support: product support cards ---- */
.topics-lead {
  color: var(--grey-text);
  font-size: 0.98rem;
  line-height: 1.65;
  max-width: 56ch;
  margin-bottom: var(--space-4);
}

.product-support {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

@media (min-width: 760px) {
  .product-support {
    grid-template-columns: repeat(2, 1fr);
  }
}

.ps-card {
  background: var(--white);
  border: 1px solid var(--grey-soft);
  border-radius: 12px;
  padding: var(--space-3);
  box-shadow: 0 1px 2px rgba(17, 19, 24, 0.03);
}

@media (min-width: 640px) {
  .ps-card {
    padding: var(--space-4);
  }
}

.ps-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-bottom: var(--space-3);
  margin-bottom: var(--space-3);
  border-bottom: 1px solid var(--grey-soft);
}

.ps-head .app-badge {
  width: 46px;
  height: 46px;
  border-radius: 11px;
  font-size: 1.25rem;
  margin-bottom: 0;
}

.ps-head h3 {
  font-size: 1.15rem;
  margin-bottom: 0.1rem;
}

.ps-head p {
  font-size: 0.85rem;
  color: var(--teal);
  font-weight: 600;
}

.ps-list {
  display: grid;
  gap: 0.7rem;
}

.ps-list li {
  position: relative;
  padding-left: 1.1rem;
  font-size: 0.92rem;
  color: #33363d;
}

.ps-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--teal);
  opacity: 0.55;
}

/* The topics are links now that the guides exist. They keep the list's text
   colour so six of them don't shout, but the underline is always on rather
   than hover-only: there is no hover on a phone, and these had no affordance
   at all there. It stays faint until hover, when it takes the accent. */
.ps-list--linked a {
  color: inherit;
  display: inline-block;
  padding-block: 0.1rem;
  text-decoration: underline;
  text-decoration-color: rgba(15, 107, 109, 0.35);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color 0.2s var(--ease), text-decoration-color 0.2s var(--ease);
}

.ps-list--linked a:hover,
.ps-list--linked a:focus-visible {
  color: var(--teal);
  text-decoration-color: var(--teal);
}

.ps-card .text-link {
  margin-top: var(--space-3);
}

/* ---- Support: general help row ---- */
.general-help {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2);
}

@media (min-width: 760px) {
  .general-help {
    grid-template-columns: repeat(3, 1fr);
  }
}

.general-help a {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  height: 100%;
  padding: var(--space-3);
  background: var(--white);
  border: 1px solid var(--grey-soft);
  border-radius: 12px;
  transition: border-color 0.22s var(--ease), transform 0.22s var(--ease);
}

.general-help a:hover,
.general-help a:focus-visible {
  border-color: rgba(15, 107, 109, 0.4);
  transform: translateY(-2px);
}

.gh-icon {
  flex-shrink: 0;
  color: var(--teal);
}

.gh-icon svg {
  width: 22px;
  height: 22px;
}

.general-help strong {
  display: block;
  font-size: 0.95rem;
  font-weight: 600;
  margin-bottom: 0.1rem;
}

.general-help span span,
.general-help a > span:nth-child(2) {
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--grey-text);
}

.gh-arrow {
  margin-left: auto;
  color: var(--teal);
  transition: transform 0.2s var(--ease);
}

.general-help a:hover .gh-arrow,
.general-help a:focus-visible .gh-arrow {
  transform: translateX(4px);
}

/* ---- About: independent-studio section ---- */
.team-intro p + p {
  margin-top: var(--space-2);
}

/* ---- Contact: tighten space above the form ---- */
.page-contact .contact-hero {
  padding-block: var(--space-5) var(--space-4);
}

/* Mobile: bring the form up the page without cramping the copy or shrinking
   touch targets. Trims roughly 70px from the hero + trust-row stack. */
@media (max-width: 559px) {
  .page-contact .contact-hero {
    padding-block: var(--space-4) var(--space-3);
  }

  .page-contact .contact-intro {
    margin-bottom: var(--space-4);
  }

  .page-contact .trust-row {
    gap: var(--space-2);
  }

  .page-contact .trust-icon {
    width: 36px;
    height: 36px;
    border-radius: 9px;
  }

  .page-contact .trust-icon svg {
    width: 17px;
    height: 17px;
  }

  .page-contact .trust-item p {
    max-width: none;
  }
}

/* Apps hero shows the products at wide sizes and the X below that. */
@media (min-width: 1100px) {
  .hero-x--narrow-only {
    display: none;
  }
}

/* The contact hero has tighter top padding than the others, so its headline
   starts higher; the X needs a correspondingly smaller, higher position. */
@media (max-width: 899px) {
  .page-contact .hero-x {
    top: -88px;
    width: 132px;
  }
}

/* ==========================================================================
   Product pages (SUMX / CLOX)
   Scoped to .page-product; reuses the existing phone, badge and card tokens.
   ========================================================================== */

.breadcrumb {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.85rem;
  color: var(--grey-text);
  margin-bottom: var(--space-3);
}

/* App icon tile above the product title. */
.product-hero-icon {
  display: flex;
  width: 72px;
  height: 72px;
  border-radius: 17px;
  overflow: hidden;
  margin-bottom: var(--space-3);
}

.breadcrumb a {
  color: var(--teal);
  font-weight: 600;
}

.breadcrumb a:hover,
.breadcrumb a:focus-visible {
  text-decoration: underline;
}

.product-hero {
  position: relative;
  background: var(--offwhite);
  overflow: hidden;
  padding-block: var(--space-5) var(--space-6);
}

.product-hero-inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
  align-items: center;
}

@media (min-width: 900px) {
  .product-hero-inner {
    grid-template-columns: 1fr auto;
    gap: var(--space-5);
  }
}

.product-hero h1 {
  font-size: clamp(2.75rem, 5vw + 1rem, 4.5rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  margin-bottom: var(--space-2);
}

.product-tagline {
  font-size: clamp(1.25rem, 1.4vw + 1rem, 1.6rem);
  font-weight: 700;
  letter-spacing: -0.01em;
  margin-bottom: var(--space-3);
}

.product-lead {
  color: var(--grey-text);
  font-size: 1.05rem;
  line-height: 1.7;
  max-width: 46ch;
}

.product-hero-visual {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
}

/* ---- Store badge row -----------------------------------------------------
   Carries the official "Get it on Google Play" artwork, used unmodified.
   SUMX ships on Android only, so one badge is all this row ever holds.

   The asset is 646x250, but 41px of that on every side is the clear space
   Google bakes into the file: the badge you actually see is the middle
   564x168. Scaling the whole image to 60px tall therefore draws the badge
   at its official 135x40, and asking a 564px-wide source to fill 135px
   leaves better than 4x for Retina. */
.store-badges {
  /* One knob for the whole row. --badge-inset is the clear space at whatever
     height the badge is currently drawn: 41 of the asset's 250px, so 16.4%.
     Deriving it rather than hard-coding a pixel value keeps the alignment
     exact at both sizes below instead of drifting by a pixel on small
     screens. */
  --badge-h: 60px;
  --badge-inset: calc(var(--badge-h) * 0.164);

  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 11px;
  /* Pulled back by that inset so the badge's visible left edge lines up with
     the copy and buttons above it instead of sitting mysteriously indented.
     The clear space is still there — it just overlaps the margin the layout
     was already leaving. */
  margin: 0 0 0 calc(var(--badge-inset) * -1);
  padding: 0;
  list-style: none;
}

.store-badges li {
  display: flex;
}

.store-badges a {
  display: inline-flex;
  /* Sized past the artwork's ~5px corners so the focus ring below traces the
     badge rather than the transparent box around it. */
  border-radius: 12px;
  transition: transform 0.2s var(--ease), opacity 0.2s var(--ease),
    filter 0.2s var(--ease);
}

/* The same 1-2px lift the .btn rules use, plus a light touch of brightness.
   Deliberately no scale and no hue change: the badge keeps its official
   proportions and colours, so this reads as feedback, not restyling.
   The global prefers-reduced-motion rule already flattens the transition. */
.store-badges a:hover,
.store-badges a:focus-visible {
  transform: translateY(-2px);
  opacity: 0.92;
  filter: brightness(1.08);
}

/* Negative offset because the anchor's box is ~10px larger than the badge on
   every side; at +3px the ring floated well clear of the artwork. */
.store-badges a:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: -7px;
}

/* Official artwork is never recoloured or cropped — only scaled, which their
   guidelines permit. Height drives it; width follows to hold the ratio. */
.store-badges img {
  height: var(--badge-h);
  width: auto;
  display: block;
}

@media (max-width: 400px) {
  .store-badges {
    --badge-h: 54px;
  }
}

/* Contextual spacing. Each of these takes a step off the normal scale and
   subtracts the artwork's own top clear space, so the badge ends up the same
   visual distance from what precedes it as any other element would be —
   without the gap looking a third too wide. */
.product-body .store-badges {
  margin-top: calc(var(--space-2) - var(--badge-inset));
}

/* The sibling selector covers the six tool pages, whose SUMX section has no
   context class of its own — anywhere a badge row follows a button row it
   gets the same gap. */
.app-info .store-badges,
.product-hero .store-badges,
.product-cta .store-badges,
.cta-row + .store-badges {
  margin-top: calc(var(--space-3) - var(--badge-inset));
}

/* Both product-page slots pair the badge with a .store-note underneath; the
   artwork's bottom clear space already covers most of that gap. */
.product-hero .store-badges + .store-note,
.product-cta .store-badges + .store-note {
  margin-top: 0;
}

/* ---- Product content sections ---- */
.product-section {
  padding-block: var(--space-6);
}

.product-section--tint {
  background: rgba(15, 107, 109, 0.045);
  border-block: 1px solid rgba(15, 107, 109, 0.1);
}

.product-section h2 {
  font-size: clamp(1.6rem, 1.8vw + 1rem, 2.1rem);
  margin-bottom: var(--space-3);
}

.product-section p {
  color: var(--grey-text);
  font-size: 1rem;
  line-height: 1.75;
  max-width: 62ch;
}

.product-section p + p {
  margin-top: var(--space-2);
}

/* Prose links underline on hover. .text-link is excluded: it is a
   standalone call to action with its own hover — the arrow slides — and
   stacking a rule under the whole thing, arrow included, reads as a glitch
   rather than an affordance. Keyboard focus is unaffected either way; the
   global :focus-visible ring above covers it. */
.product-section a:not(.btn):not(.text-link) {
  color: var(--teal);
  font-weight: 600;
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s var(--ease);
}

.product-section a:not(.btn):not(.text-link):hover,
.product-section a:not(.btn):not(.text-link):focus-visible {
  border-bottom-color: var(--teal);
}

/* ---- Feature list ---- */
.product-features {
  background: var(--offwhite);
  padding-block: var(--space-6);
}

.feature-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}

@media (min-width: 640px) {
  .feature-list {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1040px) {
  .feature-list {
    grid-template-columns: repeat(3, 1fr);
  }
}

.feature-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 11px;
  background: rgba(15, 107, 109, 0.08);
  color: var(--teal);
  margin-bottom: var(--space-2);
}

.feature-icon svg {
  width: 21px;
  height: 21px;
}

.feature-list h3 {
  font-size: 1.05rem;
  margin-bottom: 0.4rem;
}

.feature-list p {
  font-size: 0.93rem;
  line-height: 1.65;
  color: var(--grey-text);
  max-width: 34ch;
}

/* ---- Closing CTA ---- */
.product-cta {
  background: var(--offwhite);
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

/* The Apps page cards used to carry a lone .app-cta button that shrank to its
   own width. Now that the explore and waitlist buttons share a .cta-row, that
   shrink-to-fit sizing wrapped them onto separate lines with room to spare, so
   the row is left to take the card's width and .app-cta is gone. */

/* ---- Privacy page ---- */
.page-content h2 {
  font-size: 1.25rem;
  margin-top: var(--space-4);
  margin-bottom: var(--space-2);
}

/* The lead paragraph keeps the full ink weight, deliberately, now that body
   paragraphs are a step lighter. */
.privacy-intro {
  font-size: 1.05rem;
  line-height: 1.7;
  color: var(--ink);
  margin-bottom: var(--space-3);
}

.privacy-list {
  margin: var(--space-2) 0;
  padding-left: 0;
}

.privacy-list li {
  position: relative;
  padding-left: 1.2rem;
  margin-bottom: 0.45rem;
  color: var(--grey-text);
}

.privacy-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--teal);
  opacity: 0.55;
}

/* Numbered variant, for a list where the order carries the meaning rather than
   just grouping items — the purchase-verification flow. Swaps the dot marker
   for a counter so the sequence reads as steps, keeping the accent colour and
   the same indent as .privacy-list. Must stay after the rule above: the two
   ::before selectors have equal specificity, so source order decides. */
.privacy-steps {
  counter-reset: privacy-step;
}

.privacy-steps li::before {
  content: counter(privacy-step);
  counter-increment: privacy-step;
  top: 0;
  width: auto;
  height: auto;
  border-radius: 0;
  background: none;
  color: var(--teal);
  font-family: var(--font-mono);
  font-size: 0.85em;
  font-weight: 500;
  opacity: 1;
}

/* ---- SUMX support guides ---- */

/* Six guides on one page, so each needs a visible boundary the eye can catch
   while scrolling past. A rule above the heading does that without adding a
   second type size to the scale. */
.guide-heading {
  margin-top: var(--space-6);
  padding-top: var(--space-3);
  border-top: 1px solid var(--grey-soft);
  font-size: 1.55rem;
}

.guide-jump {
  margin: var(--space-4) 0 var(--space-5);
  padding: var(--space-3);
  background: var(--offwhite);
  border: 1px solid var(--grey-soft);
  border-radius: var(--radius-card);
}

.guide-jump h2 {
  margin: 0 0 var(--space-2);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--grey-text);
}

.guide-jump ol {
  counter-reset: guide-jump;
  display: grid;
  gap: 0.15rem;
}

.guide-jump a {
  display: block;
  padding: 0.45rem 0;
  font-weight: 500;
  color: var(--ink);
}

.guide-jump a::before {
  content: counter(guide-jump) ".";
  counter-increment: guide-jump;
  display: inline-block;
  width: 1.6rem;
  font-family: var(--font-mono);
  font-size: 0.85em;
  color: var(--teal);
}

.guide-jump a:hover,
.guide-jump a:focus-visible {
  color: var(--teal);
}

/* Anchored sections land under the fixed header without this. */
.page-content [id] {
  scroll-margin-top: 90px;
}

/* ---- Guide figure ----
   A screenshot with its explanation beside it rather than beneath. Guide
   screenshots answer "where is it" and "what am I looking at", and both
   questions are easier to answer when the sentence sits next to the thing
   it points at. Stacking them would also push a six-section guide to twice
   its length for no gain.

   Only used where a capture earns its place. Most of this guide is prose
   that a picture cannot improve, and a screenshot beside every heading
   would make the useful ones harder to notice. */
.guide-figure {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: flex-start;
  margin: var(--space-3) 0 var(--space-4);
  padding: var(--space-3);
  background: var(--offwhite);
  border: 1px solid var(--grey-soft);
  border-radius: var(--radius-card);
}

/* The note takes the remaining width and stops wrapping to a sliver: below
   about 460px of panel there is no room for two columns, so it takes a full
   line of its own and the device centres above it. */
.guide-figure-note {
  flex: 1 1 15rem;
  min-width: 0;
}

.guide-figure .device {
  flex-shrink: 0;
  max-width: 186px;
  margin-inline: auto;
}

/* Tighter than .page-content p: this is a caption, not body copy, and it
   sits in a panel that already separates it from the prose. */
.guide-figure-note p {
  margin: 0 0 0.6rem;
  font-size: 0.92rem;
  line-height: 1.6;
}

.guide-figure-note p:last-child {
  margin-bottom: 0;
}

/* Names the screen so a reader scanning for one can find it without
   reading the paragraph under it. */
.guide-figure-label {
  display: block;
  margin-bottom: 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--grey-text);
}

/* Three columns of prose will not fit a phone, so the table scrolls inside its
   own container rather than pushing the page sideways. tabindex makes that
   region reachable by keyboard, which a scrollable box otherwise is not. */
.table-scroll {
  overflow-x: auto;
  margin: var(--space-2) 0 var(--space-3);
  border: 1px solid var(--grey-soft);
  border-radius: var(--radius-card);
}

.table-scroll:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
}

.guide-table {
  width: 100%;
  min-width: 34rem;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.guide-table th,
.guide-table td {
  text-align: left;
  vertical-align: top;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--grey-soft);
}

.guide-table thead th {
  background: var(--offwhite);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--grey-text);
  white-space: nowrap;
}

.guide-table td {
  color: var(--grey-text);
  line-height: 1.55;
}

.guide-table td:first-child {
  color: var(--ink);
}

.guide-table tbody tr:last-child th,
.guide-table tbody tr:last-child td {
  border-bottom: 0;
}

.privacy-host {
  font-family: var(--font-mono);
  font-size: 0.9em;
}

.privacy-updated {
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid var(--grey-soft);
  font-size: 0.9rem;
  color: var(--grey-text);
}

.page-content a:not(.btn) {
  color: var(--teal);
  font-weight: 600;
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s var(--ease);
}

.page-content a:not(.btn):hover,
.page-content a:not(.btn):focus-visible {
  border-bottom-color: var(--teal);
}

/* ==========================================================================
   SUMX product page — all-in-one positioning
   Additive only: existing tokens, spacing scale and card treatments.
   No new colours, no new type families.
   ========================================================================== */

/* ---- Store slot supporting note ---- */
.store-note {
  margin-top: var(--space-2);
  font-size: 0.88rem;
  line-height: 1.6;
  color: var(--grey-text);
  max-width: 44ch;
}

/* ---- Section intro (used where a section leads a grid rather than prose) ---- */
.section-intro {
  max-width: 62ch;
  margin-bottom: var(--space-4);
}

.section-intro h2 {
  font-size: clamp(1.6rem, 1.8vw + 1rem, 2.1rem);
  margin-bottom: var(--space-2);
}

.section-intro p {
  color: var(--grey-text);
  font-size: 1rem;
  line-height: 1.75;
}

/* ---- The six tools ------------------------------------------------------
   Six cards divide evenly at both breakpoints (2 x 3, then 3 x 2), so no
   row is ever left with a single orphaned card. */
.tool-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
}

@media (min-width: 620px) {
  .tool-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1040px) {
  .tool-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* A column so the call to action can be pushed to the foot of the card.
   The grid already stretches cards to a common height per row, so without
   this the links sit wherever each description happens to end. */
.tool-card {
  display: flex;
  flex-direction: column;
  padding: var(--space-3);
  border: var(--border);
  border-radius: var(--radius-card);
  background: var(--white);
}

/* Takes up the slack left by a shorter description, so every link in a row
   lands on the same line. Cards without one are unaffected.

   Scoped through .tool-card because .product-section p + p sets a top margin
   on any paragraph following another, and would otherwise outrank the auto
   that does the pushing. */
.tool-card .tool-card-cta {
  margin-top: auto;
  padding-top: var(--space-2);
}

.tool-card .feature-icon {
  width: 40px;
  height: 40px;
  border-radius: 10px;
}

.tool-card .feature-icon svg {
  width: 19px;
  height: 19px;
}

.tool-card h3 {
  font-size: 1.02rem;
  margin-bottom: 0.4rem;
}

.tool-card p {
  font-size: 0.92rem;
  line-height: 1.65;
  color: var(--grey-text);
}

/* ---- Paired feature cards -----------------------------------------------
   Overrides the three-column .feature-list rule so four cards read as a
   deliberate 2 x 2 block instead of an unbalanced 3 + 1. */
@media (min-width: 640px) {
  .feature-list--two {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1040px) {
  .feature-list--two {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-4) var(--space-5);
  }
}

.feature-list--two p {
  max-width: 48ch;
}

.feature-list code,
.product-section code {
  font-family: var(--font-mono);
  font-size: 0.88em;
  color: var(--ink);
  overflow-wrap: anywhere;
}

/* ---- Free vs SUMX Pro ---- */
.plan-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
}

@media (min-width: 760px) {
  .plan-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

.plan-card {
  display: flex;
  flex-direction: column;
  padding: var(--space-4) var(--space-3);
  border: var(--border);
  border-radius: var(--radius-card);
  background: var(--white);
}

@media (min-width: 640px) {
  .plan-card {
    padding: var(--space-4);
  }
}

/* The paid tier is marked with the existing teal at low opacity — the same
   tint already used by .product-section--tint. */
.plan-card--pro {
  border-color: rgba(15, 107, 109, 0.32);
  background: rgba(15, 107, 109, 0.045);
}

.plan-card h3 {
  font-size: 1.25rem;
  margin-bottom: 0.35rem;
}

/* Typed selectors: .product-section p is (0,1,1) and would otherwise win
   over a bare class. */
p.plan-meta {
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--teal);
  margin-bottom: var(--space-3);
  max-width: none;
}

.plan-list {
  display: grid;
  gap: 0.6rem;
}

.plan-list li {
  position: relative;
  padding-left: 1.7rem;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--grey-text);
}

.plan-list li::before {
  content: "";
  position: absolute;
  left: 0.2rem;
  top: 0.35em;
  width: 11px;
  height: 6px;
  border-left: 2px solid var(--teal);
  border-bottom: 2px solid var(--teal);
  transform: rotate(-45deg);
}

p.plan-reassure {
  margin-top: var(--space-4);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
}

p.plan-note {
  margin-top: var(--space-1);
  font-size: 0.88rem;
  line-height: 1.6;
  color: var(--grey-text);
  max-width: 62ch;
}

/* ---- Two-column detail lists (personalisation) ---- */
.product-section--soft {
  background: var(--offwhite);
}

.detail-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3) var(--space-4);
  margin-top: var(--space-3);
}

@media (min-width: 620px) {
  .detail-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

.detail-grid h3 {
  font-size: 1rem;
  margin-bottom: 0.25rem;
}

/* The privacy bullet treatment is reused here; it needs no page scoping. */
.detail-grid .privacy-list li:last-child {
  margin-bottom: 0;
}

/* ==========================================================================
   CLOX product page — pre-development positioning
   Additive only. Reuses the SUMX card and grid primitives above; the only
   CLOX-specific colours live inside the existing conceptual visuals.
   ========================================================================== */

/* ---- Product status line -------------------------------------------------
   Both product pages state their stage once, using the same dot-and-text
   .card-status chip as the Home product cards — never a pill that could be
   mistaken for a disabled download button. */
.status-line {
  margin-top: var(--space-4);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* Beside a closing CTA the chip leads the block rather than following copy. */
.status-line--tight {
  margin-top: 0;
  margin-bottom: var(--space-2);
}

/* Hero scale: matches .eyebrow rather than the smaller card chip. */
.product-hero .card-status {
  margin-bottom: 0;
  font-size: 0.78rem;
  letter-spacing: 0.14em;
}

p.status-note {
  margin-top: var(--space-2);
  font-size: 0.88rem;
  line-height: 1.6;
  color: var(--grey-text);
  max-width: 48ch;
}

/* ---- Concept-visual disclosure ---- */
.concept-note {
  margin-top: var(--space-2);
  margin-inline: auto;
  max-width: 32ch;
  font-size: 0.78rem;
  line-height: 1.55;
  color: var(--grey-text);
  text-align: center;
}

/* ---- Two-up blocks: languages/themes, personalisation/privacy, model/privacy ---- */
.concept-pair {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
}

@media (min-width: 860px) {
  .concept-pair {
    grid-template-columns: repeat(2, 1fr);
  }
}

.concept-pair h3 {
  font-size: 1.1rem;
  margin-bottom: var(--space-2);
}

.concept-pair .clox-themes {
  margin-top: var(--space-3);
}

/* ---- Programming-language labels ----------------------------------------
   Text only, in the brand's existing mono face. No third-party logos. */
.lang-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: var(--space-3);
}

.lang-list li {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--ink);
  padding: 0.4rem 0.75rem;
  border: var(--border);
  border-radius: var(--radius);
  background: var(--white);
}

/* ---- Product status chip -------------------------------------------------
   One treatment, three places: the Home product cards, both product-page
   heroes, and the CLOX feedback CTA. */
.card-status {
  display: inline-flex;
  /* These labels wrap on narrow screens ("COMING SOON TO GOOGLE PLAY",
     "CURRENTLY IN PRE-DEVELOPMENT"). Centring left the dot floating against
     the middle of a two-line block; aligning to the start keeps it on the
     first line, where it reads as a bullet rather than a stray mark. */
  align-items: flex-start;
  line-height: 1.5;
  gap: 0.45rem;
  margin-bottom: 0.6rem;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--grey-text);
}

.card-status::before {
  content: "";
  flex-shrink: 0;
  width: 6px;
  height: 6px;
  /* Optically centres the dot on the first line rather than the whole block. */
  margin-top: calc((1.5em - 6px) / 2);
  border-radius: 50%;
  background: var(--teal);
}

/* Both dark surfaces the chip sits on take the same lighter grey. */
.product-body .card-status,
.product-section--dark .card-status {
  color: var(--grey-on-dark);
}

/* ---- Dark showcase band --------------------------------------------------
   One per product page, carrying its strongest section. Colour treatment is
   lifted from the existing .strip / .products bands: --ink ground, --offwhite
   headings, --grey-on-dark body, #23262d hairlines. No new colours.

   Teal is deliberately not reused for text or icons here — at 2.9:1 on --ink
   it fails AA — so the accent survives only as the .card-status dot, which is
   decorative. */
.product-section--dark {
  background: var(--ink);
  color: var(--offwhite);
  border-block: 1px solid #23262d;
}

.product-section--dark h2,
.product-section--dark h3 {
  color: var(--offwhite);
}

.product-section--dark p,
.product-section--dark .section-intro p,
.product-section--dark .feature-list p,
.product-section--dark .tool-card p {
  color: var(--grey-on-dark);
}

.product-section--dark .eyebrow {
  color: var(--grey-on-dark);
}

.product-section--dark code {
  color: var(--offwhite);
}

.product-section--dark .tool-card {
  background: var(--ink-card);
  border-color: var(--ink-border);
}

/* Icon chips invert: light glyph on a faint light wash rather than teal on
   a teal wash, which would disappear against --ink. */
.product-section--dark .feature-icon {
  background: rgba(247, 247, 245, 0.08);
  color: var(--offwhite);
}

.product-section--dark .lang-list li {
  color: var(--offwhite);
  background: var(--ink-card);
  border-color: var(--ink-border);
}

.product-section--dark .themes-label {
  color: var(--grey-on-dark);
}

/* .btn-secondary is --ink text on a transparent ground, so on an --ink
   section the label renders at exactly the background colour and vanishes.
   The inverted pair belongs to every dark section, not to any one page. */
.product-section--dark .btn-secondary {
  color: var(--offwhite);
  border-color: rgba(247, 247, 245, 0.22);
}

.product-section--dark .btn-secondary:not([disabled]):hover,
.product-section--dark .btn-secondary:not([disabled]):focus-visible {
  color: var(--teal-on-dark);
  border-color: var(--teal-on-dark);
}

/* Muted through colour rather than opacity: fading a whole control over a
   dark ground crushes the border to almost nothing, leaving an empty pill. */
.product-section--dark .btn-secondary[disabled] {
  color: var(--grey-on-dark);
  border-color: rgba(247, 247, 245, 0.14);
}

.product-section--dark a:not(.btn) {
  color: var(--offwhite);
  border-bottom-color: rgba(247, 247, 245, 0.4);
}

.product-section--dark a:not(.btn):hover,
.product-section--dark a:not(.btn):focus-visible {
  border-bottom-color: var(--offwhite);
}

/* ---- Support: product with no guides yet ---- */
.ps-note {
  font-size: 0.9rem;
  line-height: 1.65;
  color: var(--grey-text);
}

.ps-note + .ps-note {
  margin-top: var(--space-2);
}

.ps-note a {
  color: var(--teal);
  font-weight: 600;
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s var(--ease);
}

.ps-note a:hover,
.ps-note a:focus-visible {
  border-bottom-color: var(--teal);
}

/* ==========================================================================
   SUMX pricing — Free / Pro
   Extends the existing .plan-* components rather than introducing a separate
   pricing system. Every colour, radius, border and step comes from the
   tokens already defined at the top of this file.
   ========================================================================== */

.plan-price {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin-bottom: 0.35rem;
}

.plan-amount {
  font-size: clamp(2.1rem, 2vw + 1.4rem, 2.6rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--ink);
}

.plan-amount-note {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--grey-text);
}

/* Typed selector: .product-section p is (0,1,1) and outranks a bare class. */
p.plan-blurb {
  font-size: 0.95rem;
  line-height: 1.65;
  color: var(--grey-text);
  margin-bottom: 0;
}

/* ---- Introductory launch price ------------------------------------------
   Currently OFF. The regular price and the launch block both live in the
   markup, so switching between them is an attribute change and nothing else.

     TO ENABLE :  remove `hidden` from [data-launch-price]
                  add    `hidden` to  [data-regular-price]
     TO DISABLE:  reverse those two edits

   Deliberately understated: no timer, no countdown and no urgency language.
   The attribute selector is (0,2,0) so it beats .plan-price's display rule
   without needing !important. */
[data-launch-price][hidden],
[data-regular-price][hidden] {
  display: none;
}

.plan-launch-note {
  font-size: 0.9rem;
  color: var(--grey-text);
  margin-bottom: var(--space-3);
}

.plan-was-value {
  text-decoration: line-through;
}

/* ---- PRO marker ----------------------------------------------------------
   Used beside a feature name to identify it as part of SUMX Pro. The word
   itself carries the meaning, so this never depends on colour alone; each
   marker also carries visually hidden text for screen readers.
   white-space guards against the label wrapping away from its heading. */
.pro-tag {
  display: inline-block;
  margin-left: 0.5rem;
  padding: 0.16rem 0.42rem;
  border: 1px solid rgba(15, 107, 109, 0.35);
  border-radius: var(--radius);
  background: rgba(15, 107, 109, 0.06);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--teal);
  vertical-align: 0.18em;
  white-space: nowrap;
}

/* ---- Free / Pro comparison ---- */
.plan-card--compare .plan-list {
  margin-top: var(--space-3);
}

p.plan-card-lead {
  font-size: 0.95rem;
  line-height: 1.65;
  color: var(--grey-text);
  margin-bottom: 0;
}

/* ---- SUMX Pro FAQ ---- */
.faq-list {
  margin-top: var(--space-4);
}

.faq-list dt {
  font-weight: 700;
  color: var(--ink);
  margin-top: var(--space-3);
}

.faq-list dt:first-child {
  margin-top: 0;
}

.faq-list dd {
  margin: 0.4rem 0 0;
  color: var(--grey-text);
  line-height: 1.7;
}

/* ==========================================================================
   SUMX accents and adaptive launcher icon
   The swatches and icons are drawn in CSS from the app's own palette
   (lib/design/nume_theme.dart), so they stay in step with the build without
   shipping 24 image assets. These stay illustrative: the screenshots show
   the app, and a launcher icon is what the app leaves behind on a home
   screen, which no capture of the app itself contains.
   ========================================================================== */

/* The palette sits in its own panel so the swatches read as a control
   rather than loose dots, and so the note beneath can never collide with
   the icon walls that follow. */
.accent-panel {
  padding: var(--space-3);
  border: var(--border);
  border-radius: var(--radius-card);
  background: var(--white);
  margin-bottom: var(--space-3);
}

.accent-label {
  display: block;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--grey-text);
  margin-bottom: var(--space-3);
}

/* Swatches and their note share a row on wide screens, so the note fills
   the panel instead of wrapping at its reading width and leaving the right
   half empty. Stacks below 900px. */
.accent-panel-body {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  align-items: center;
}

@media (min-width: 900px) {
  .accent-panel-body {
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--space-4);
  }
}

.accent-panel-body .accent-note {
  max-width: none;
}

/* ---- Palette row ---- */
.accent-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.accent-swatch {
  position: relative;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--swatch);
}

/* The free accent is ringed and ticked, mirroring the in-app picker. The
   tick is a shape, not a colour cue, and every swatch also carries its
   name as visually hidden text. */
.accent-swatch--free {
  box-shadow: 0 0 0 2px var(--white), 0 0 0 4px var(--swatch);
}

.accent-swatch--free::after {
  content: "";
  position: absolute;
  left: 11px;
  top: 12px;
  width: 11px;
  height: 6px;
  border-left: 2px solid var(--white);
  border-bottom: 2px solid var(--white);
  transform: rotate(-45deg);
}

.accent-orange       { --swatch: #E77C3C; }
.accent-blue         { --swatch: #5F96CE; }
.accent-green        { --swatch: #6FA47C; }
.accent-violet       { --swatch: #8A6CC3; }
.accent-graphite     { --swatch: #777774; }
.accent-claret       { --swatch: #B45F68; }
.accent-teal         { --swatch: #438985; }
.accent-gold         { --swatch: #B58A3C; }
.accent-mulberry     { --swatch: #9C607F; }
.accent-bronze       { --swatch: #8C7560; }
.accent-sage         { --swatch: #7F9180; }
.accent-indigo       { --swatch: #707A9A; }

/* ---- Launcher icon walls -------------------------------------------------
   Two panels showing the full set: every accent as it appears on a dark
   home screen and on a light one. Showing all twelve at once is the point —
   the scale of the set is the feature. */
.icon-walls {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
}

@media (min-width: 820px) {
  .icon-walls {
    grid-template-columns: repeat(2, 1fr);
  }
}

.icon-wall {
  padding: var(--space-3);
  border-radius: var(--radius-card);
}

.icon-wall--dark {
  background: var(--ink);
}

/* A warm light ground rather than white: the tiles are #F7F4EF, so on white
   they lean on their hairline alone and the panel reads faint beside the
   dark one. This is also closer to a light icon sitting on a wallpaper. */
.icon-wall--light {
  background: #EDEAE4;
}

.icon-wall-label {
  display: block;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-bottom: var(--space-3);
}

.icon-wall--dark .icon-wall-label {
  color: var(--grey-on-dark);
}

.icon-wall--light .icon-wall-label {
  color: var(--grey-text);
}

.icon-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.85rem;
  justify-items: center;
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 1040px) {
  .icon-grid {
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }
}

/* The icon itself: a 2x2 key cluster on a rounded tile, with the equals
   key carrying the accent — the same construction as the shipped icons.
   Each carries a hairline so it separates from the panel behind it, the
   way an icon reads against a wallpaper. */
.sumx-icon {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 3px;
  width: 52px;
  height: 52px;
  padding: 9px;
  border-radius: 12px;
}

.sumx-icon i {
  display: grid;
  place-items: center;
  border-radius: 4px;
  font-family: var(--font-body);
  font-size: 9px;
  font-weight: 700;
  font-style: normal;
  line-height: 1;
}

.sumx-icon--dark {
  background: #171816;
  border: 1px solid var(--ink-border);
}

.sumx-icon--dark i {
  background: #2B2B2B;
  color: #E4E4E1;
}

.sumx-icon--light {
  background: #F7F4EF;
  border: 1px solid var(--grey-soft);
}

.sumx-icon--light i {
  background: #EFEBE4;
  color: #26271F;
}

/* Equals key: the accent, in both variants. */
.sumx-icon .icon-eq {
  background: var(--swatch);
  color: #fff;
}

p.accent-note {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.7;
  color: var(--grey-text);
  max-width: 62ch;
}

p.accent-note--after {
  margin-top: var(--space-3);
}

/* The remaining personalisation options, as a footnote row beneath the
   accent and icon showcase. Reuses the .plan-list tick treatment. */
.accent-extras {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem var(--space-3);
  margin: var(--space-3) 0 0;
  padding: 0;
  list-style: none;
}

.accent-extras li {
  position: relative;
  padding-left: 1.7rem;
  font-size: 0.95rem;
  color: var(--grey-text);
}

.accent-extras li::before {
  content: "";
  position: absolute;
  left: 0.2rem;
  top: 0.35em;
  width: 11px;
  height: 6px;
  border-left: 2px solid var(--teal);
  border-bottom: 2px solid var(--teal);
  transform: rotate(-45deg);
}
