/*
 * Mechanica landing page — styles.
 *
 * Palette, spacing and typefaces come from docs/tech/design-system.md in the
 * mechanica repo (Professional Industrial Dark Mode). Keep the tokens in sync
 * with that document; it is the source of truth.
 *
 * Deliberately dark-only. This is a brand look, not a preference, so there is
 * no prefers-color-scheme light variant.
 *
 * Type SIZES are web sizes, not the app's pt values. The design system's
 * 30pt "Title" is a phone screen heading; a landing-page hero needs far more.
 * The token ROLES are honoured (Rajdhani Bold uppercase for headings, Rubik for
 * body, Share Tech Mono for numerics); the scale is fluid via clamp().
 */

/* ---------- Fonts ----------
   Self-hosted, deliberately. A `<link>` to fonts.googleapis.com sends every
   visitor's IP to Google before the page paints, which is the objection
   citostudio.nl already records against it ("a GDPR risk for an EU company")
   and which is at its sharpest on /privacy. Nothing here makes a third-party
   request.

   These are Google's OWN woff2 subsets, fetched from fonts.gstatic.com, so the
   bytes are identical to what the CDN served and no conversion tool was
   involved. latin + latin-ext only: the site is English today and Turkish and
   German need latin-ext, and a browser downloads a subset only if the page uses
   a character in its range.

   Rubik ships as ONE variable file per subset. Google returns the same file for
   400, 500 and 700, so it is declared once with a weight range; three rules over
   three copies of the same bytes would download it twice.

   All three faces are SIL OFL 1.1. The licence travels with them in
   assets/fonts/OFL.txt, which is what the OFL asks for. */


@font-face {
  font-family: 'Rajdhani';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/assets/fonts/rajdhani-700-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;
}

@font-face {
  font-family: 'Rajdhani';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/assets/fonts/rajdhani-700-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;
}

@font-face {
  font-family: 'Rubik';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(/assets/fonts/rubik-variable-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;
}

@font-face {
  font-family: 'Rubik';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(/assets/fonts/rubik-variable-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;
}

@font-face {
  font-family: 'Share Tech Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/share-tech-mono-400-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;
}

:root {
  color-scheme: dark;

  /* Base */
  --bg-primary: #0F1115;
  --bg-panel: #242A33;
  --divider: #323A45;

  /* Text */
  --text-primary: #E6EDF3;
  --text-secondary: #9AA4AF;
  --text-muted: #6B7480;

  /* Functional */
  --accent-cyan: #5B8FB8;
  --accent-green: #4A9B6E;
  --accent-orange: #C45C4A;
  --accent-gold: #C49A4B;

  /* Spacing */
  --xs: 4px;
  --sm: 8px;
  --md: 12px;
  --lg: 16px;
  --xl: 24px;
  --xxl: 48px;

  --radius: 8px;

  /* Typefaces */
  --font-display: 'Rajdhani', 'Arial Narrow', system-ui, sans-serif;
  --font-body: 'Rubik', system-ui, -apple-system, 'Helvetica Neue', sans-serif;
  --font-mono: 'Share Tech Mono', ui-monospace, 'SFMono-Regular', monospace;

  --max-width: 1080px;
}

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

body {
  margin: 0;
  background: var(--bg-primary);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: clamp(16px, 1.05vw + 13px, 18px);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  line-height: 1.1;
  margin: 0;
}

p { margin: 0; }

a { color: var(--accent-cyan); }

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

.wrap {
  width: 100%;
  max-width: var(--max-width);
  margin-inline: auto;
  padding-inline: var(--xl);
}

/* ---------- Legal pages (privacy, and terms when it lands) ----------
   Long-form prose, which the landing page has no need of. Narrower than
   --max-width on purpose: a legal page is read line by line, and a 1080px
   measure is roughly twice the ~70 characters that stays readable. */

.legal {
  max-width: 760px;
  padding-block: var(--xxl);
}

.legal h1 { font-size: clamp(30px, 4vw + 12px, 44px); margin-bottom: var(--xl); }
.legal h2 { font-size: clamp(20px, 1.4vw + 15px, 26px); margin-top: var(--xxl); margin-bottom: var(--md); }
.legal h3 {
  font-size: clamp(15px, 0.6vw + 13px, 17px);
  margin-top: var(--xl);
  margin-bottom: var(--sm);
  color: var(--accent-cyan);
}

.legal p, .legal ul { margin-bottom: var(--lg); }
.legal p { color: var(--text-secondary); }
.legal strong { color: var(--text-primary); font-weight: 700; }

.legal ul { padding-left: var(--xl); color: var(--text-secondary); }
.legal li { margin-bottom: var(--sm); }

.legal code {
  font-family: var(--font-mono);
  font-size: 0.92em;
  color: var(--text-primary);
}

/* The processor table. Wrapped in its own scroll container so a narrow phone
   scrolls the table rather than the whole page sideways. */
.legal table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: var(--lg);
  font-size: 0.94em;
  color: var(--text-secondary);
}

.legal th, .legal td {
  text-align: left;
  padding: var(--sm) var(--md);
  border-bottom: 1px solid var(--divider);
  vertical-align: top;
}

.legal th {
  color: var(--text-primary);
  font-weight: 500;
  border-bottom-color: var(--text-muted);
}

/* ---------- Header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: color-mix(in srgb, var(--bg-primary) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--divider);
}

.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--lg);
  min-height: 64px;
}

/* Brand lockup. The wordmark is the brushed-metal art from the splash icon,
   cut out of its BgPrimary ground, so it composites over the translucent
   header rather than showing a rectangle. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--md);
  text-decoration: none;
  min-width: 0;
}

.brand-mark {
  width: 36px;
  height: 36px;
  border-radius: 9px;
  border: 1px solid var(--divider);
  flex: none;
}

.brand-wordmark {
  width: clamp(132px, 18vw, 180px);
  height: auto;
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sm);
  padding: var(--md) var(--xl);
  border: 1px solid var(--divider);
  border-radius: var(--radius);
  background: var(--bg-panel);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 16px;
  text-decoration: none;
  cursor: pointer;
  transition: border-color 120ms ease, transform 120ms ease;
}

.btn:hover { border-color: var(--accent-cyan); }
.btn:active { transform: translateY(1px); }

.btn-primary {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent-cyan) 24%, var(--bg-panel)),
    var(--bg-panel));
  border-color: color-mix(in srgb, var(--accent-cyan) 60%, var(--divider));
}

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

/* ---------- Hero ---------- */

.hero {
  position: relative;
  padding-block: clamp(var(--xxl), 8vw, 120px);
  border-bottom: 1px solid var(--divider);
  /* Placeholder ground until the garage still / loop lands. Replace the
     gradient with the real asset rather than layering one on top of it. */
  background:
    radial-gradient(120% 90% at 70% 15%,
      color-mix(in srgb, var(--accent-gold) 12%, transparent), transparent 60%),
    radial-gradient(100% 80% at 15% 85%,
      color-mix(in srgb, var(--accent-cyan) 14%, transparent), transparent 65%),
    var(--bg-primary);
}

.hero .wrap {
  display: grid;
  gap: var(--xxl);
  align-items: center;
}

@media (min-width: 860px) {
  .hero .wrap { grid-template-columns: 1fr 1fr; }
}

.hero h1 {
  font-size: clamp(40px, 6.5vw, 76px);
  margin-bottom: var(--lg);
}

.hero .lede {
  color: var(--text-secondary);
  font-size: clamp(17px, 1.4vw + 13px, 21px);
  max-width: 34ch;
  margin-bottom: var(--xl);
}

.hero-visual {
  display: grid;
  place-items: center;
  position: relative;
}

/* Glow behind the tile, so the icon reads as lit rather than pasted on. */
.hero-visual::before {
  content: '';
  position: absolute;
  inset: 8%;
  border-radius: 50%;
  background: radial-gradient(closest-side,
    color-mix(in srgb, var(--accent-orange) 34%, transparent), transparent);
  filter: blur(48px);
  z-index: 0;
}

.app-tile {
  position: relative;
  z-index: 1;
  width: min(340px, 68vw);
  height: auto;
  /* Roughly the iOS squircle proportion, which is what makes it read as an
     app icon rather than a photo. */
  border-radius: 22.5%;
  border: 1px solid var(--divider);
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.55);
}

.cta-row { display: flex; flex-wrap: wrap; gap: var(--md); }

/* ---------- Store badges ---------- */

/* Apple's badge is artwork-tight; Google's bakes 41px of clear space into a
   250px-tall image, so its content is only 67.2% of the file. Rendering both at
   the same height makes the Play badge look noticeably smaller. The Play image
   is therefore drawn ~1.49x taller and pulled back in with negative margins, so
   the two match optically and sit the same distance apart. Both are used
   unmodified, which is what Apple's and Google's guidelines require. */
.badge-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--md);
  margin-top: var(--xl);
}

.badge {
  display: inline-flex;
  align-items: center;
  border-radius: var(--radius);
  transition: opacity 120ms ease, transform 120ms ease;
}

.badge img { height: 54px; width: auto; }

.badge-play img {
  height: 80px;
  /* 41/646 and 41/250 of the rendered box, reclaimed so the clear space Google
     bakes in does not read as an extra gap. */
  margin: -13px;
}

.badge:hover { transform: translateY(-1px); }

.badge.is-soon {
  opacity: 0.45;
  cursor: default;
  pointer-events: none;
}

.badge.is-soon:hover { transform: none; }

/* ---------- Features ---------- */

.section { padding-block: clamp(var(--xxl), 7vw, 96px); }

.section > .wrap > h2 {
  font-size: clamp(26px, 3vw, 38px);
  margin-bottom: var(--xl);
}

.features {
  display: grid;
  gap: var(--lg);
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}

.feature {
  padding: var(--xl);
  border: 1px solid var(--divider);
  border-radius: var(--radius);
  background: var(--bg-panel);
}

.feature h3 {
  font-size: 20px;
  margin-bottom: var(--sm);
  color: var(--text-primary);
}

.feature p { color: var(--text-secondary); font-size: 16px; }

/* ---------- Footer ---------- */

.site-footer {
  border-top: 1px solid var(--divider);
  padding-block: var(--xl);
  color: var(--text-muted);
  font-size: 14px;
}

.site-footer .wrap {
  display: flex;
  flex-wrap: wrap;
  gap: var(--lg);
  align-items: center;
  justify-content: space-between;
}

.footer-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--sm);
}

.footer-brand img { border-radius: 6px; }

.site-footer nav { display: flex; flex-wrap: wrap; gap: var(--lg); }
.site-footer a { color: var(--text-secondary); text-decoration: none; }
.site-footer a:hover { color: var(--text-primary); }

/* ---------- Utilities ---------- */

body.centered {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--xl);
  text-align: center;
}

body.centered h1 { font-size: clamp(26px, 4vw, 40px); margin-bottom: var(--md); }
body.centered p { color: var(--text-secondary); margin-bottom: var(--xl); }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (max-width: 480px) {
  .wrap { padding-inline: var(--lg); }
  .brand-mark { width: 32px; height: 32px; }
  .brand-wordmark { width: 120px; }
  .site-header .btn { padding: 10px var(--lg); font-size: 15px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
