/* Unio marketing site.

   The palette is not designed here. It is lifted verbatim from the app's own
   light theme (html[data-theme="light"] in the app's index.html), because the
   site and the product have to be the same object: cobalt is you, coral is
   your partner, green is the thing that drives action.

   Light world, committed to rather than defaulted into. The one real problem
   it creates is that every screenshot on this site is ALSO the app's light
   theme, so a pure white page would leave the phones with no edge. Two things
   fix that and both are deliberate: the ground is a cool off-white rather than
   #fff so a white app screen still separates from it, and the phone bezels
   stay dark graphite, which is both what the hardware looks like and the only
   strong dark mass on the page. Every surface paints its own background
   explicitly. */

:root {
  color-scheme: light;

  /* Ground and surfaces. Not pure white: the app screens are white, and they
     have to sit ON something. */
  --bg: #f5f7fa;
  --panel: #ffffff;
  --panel-2: #eef1f5;
  --border: #e4e8ee;
  --border-soft: #e9edf2;

  /* Ink. The muted grey keeps a slight blue bias so it belongs to the ground
     rather than reading as a neutral dropped on top of it. */
  --text: #111318;
  --muted: #686d7c;
  --dim: #8a90a0;

  /* The three jobs. Never used decoratively: --me and --partner mean a
     person, --accent means an action or the moment the two resolve into one.
     The green deepens on white, exactly as it does in the app, because the
     electric lime it uses on dark is a highlighter on this ground. */
  --me: #4a8dbf;
  --partner: #f37c62;
  --accent: #3be76b;
  --me-ink: #2c6c96;
  --partner-ink: #b03f22;
  /* Green as TEXT needs to go further than green as a fill, or it fails
     contrast against white. */
  --accent-ink: #0f7a38;
  --on-accent: #052a17;
  /* The one semantic amber, deepened for white the same way. */
  --warn: #9a6400;
  /* Danger. Separate from --partner on purpose: coral means a person here, so
     an error may not borrow it. */
  --danger: #c2452f;

  --radius: 16px;
  --radius-lg: 24px;
  --radius-pill: 999px;

  --font: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* Six sizes, which is the ceiling for a marketing page. */
  --t-display: clamp(2.5rem, 6.4vw, 4.4rem);
  --t-h2: clamp(1.85rem, 3.6vw, 2.7rem);
  --t-h3: 1.3rem;
  --t-body: 1.0625rem;
  --t-sm: 0.9375rem;
  --t-label: 0.78rem;

  /* 4/8 scale, so any step can be halved without inventing a new number. */
  --s1: 4px;  --s2: 8px;  --s3: 16px; --s4: 24px;
  --s5: 32px; --s6: 48px; --s7: 64px; --s8: 96px; --s9: 128px;

  /* On white, depth is shadow. The hairline of light that carried depth on the
     dark ground does nothing here, and the glows the dark theme used read as
     smudge, so they are gone rather than dimmed. Shadows stay low opacity and
     wide: if the shadow is the first thing you notice, it is wrong. */
  --edge: 0 1px 2px rgba(17, 19, 24, .04);
  --card-shadow: 0 1px 2px rgba(17, 19, 24, .05), 0 8px 24px -14px rgba(17, 19, 24, .22);
  --float: 0 30px 60px -24px rgba(17, 19, 24, .34), 0 6px 18px -8px rgba(17, 19, 24, .12);
  --wash: radial-gradient(120% 70% at 50% -10%, #ffffff 0%, var(--bg) 58%);

  /* The closing band. A token rather than a hex in two page stylesheets,
     which is how it ended up wrong when the theme changed. */
  --band: linear-gradient(165deg, #f2fbf4 0%, #ffffff 58%);
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

body {
  margin: 0;
  background: var(--bg);
  background-image: var(--wash);
  background-repeat: no-repeat;
  color: var(--text);
  font-family: var(--font);
  font-size: var(--t-body);
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

a { color: inherit; }

::selection { background: color-mix(in srgb, var(--accent) 45%, transparent); color: var(--text); }

:focus-visible {
  outline: 2px solid var(--accent-ink);
  outline-offset: 3px;
  border-radius: 6px;
}

/* ---------------------------------------------------------------- layout */

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

.section { padding-block: clamp(var(--s7), 9vw, var(--s9)); }
.section-tight { padding-block: clamp(var(--s6), 6vw, var(--s8)); }

/* A hairline that fades out at both ends, so sections are separated without a
   hard rule running the full width of a dark page. */
.rule {
  height: 1px;
  border: 0;
  margin: 0;
  background: linear-gradient(90deg, transparent, var(--border) 18%, var(--border) 82%, transparent);
}

/* ------------------------------------------------------------ typography */

h1, h2, h3, h4 { margin: 0; font-weight: 800; }

.display {
  font-size: var(--t-display);
  line-height: 1.03;
  letter-spacing: -.035em;
  text-wrap: balance;
}

h2, .h2 {
  font-size: var(--t-h2);
  line-height: 1.08;
  letter-spacing: -.03em;
  text-wrap: balance;
}

h3, .h3 {
  font-size: var(--t-h3);
  line-height: 1.25;
  letter-spacing: -.015em;
  font-weight: 700;
}

p { margin: 0; }

.lede {
  font-size: clamp(1.0625rem, 1.6vw, 1.25rem);
  line-height: 1.55;
  color: var(--muted);
  max-width: 54ch;
  text-wrap: pretty;
}

.body-muted { color: var(--muted); max-width: 62ch; }

/* Uppercase eyebrow. Earns its letter-spacing because it is set small. */
.label {
  font-size: var(--t-label);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
}

/* The one typographic move that carries the brand: a word tinted to whichever
   of the three jobs it names. Used in headlines, sparingly. */
.t-me      { color: var(--me-ink); }
.t-partner { color: var(--partner-ink); }
.t-accent  { color: var(--accent-ink); }

/* -------------------------------------------------------------- controls */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  /* Roughly double the vertical padding horizontally, which is what keeps a
     button from reading as a cramped box. */
  padding: 15px 28px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font: inherit;
  font-size: var(--t-sm);
  font-weight: 700;
  letter-spacing: -.01em;
  text-decoration: none;
  cursor: pointer;
  transition: transform .14s ease, background-color .14s ease,
              border-color .14s ease, box-shadow .14s ease, color .14s ease;
}
.btn:active { transform: translateY(1px) scale(.99); }

.btn-primary {
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: 0 2px 8px -2px color-mix(in srgb, var(--accent) 45%, transparent);
}
.btn-primary:hover { background: #2fd95f; box-shadow: 0 4px 14px -4px color-mix(in srgb, var(--accent) 55%, transparent); }

.btn-ghost {
  background: transparent;
  color: var(--text);
  border-color: var(--border);
}
.btn-ghost:hover { border-color: #c3cad4; background: rgba(17, 19, 24, .035); }

.btn-block { width: 100%; }

/* App Store badge. Drawn rather than pulled from Apple's asset so it sits on
   the dark ground at the same weight as everything else. */
.store {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  padding: 11px 22px 11px 18px;
  border-radius: 14px;
  background: #111318;
  color: #ffffff;
  text-decoration: none;
  transition: transform .14s ease, box-shadow .14s ease;
}
.store:hover { transform: translateY(-1px); box-shadow: 0 14px 30px -14px rgba(17, 19, 24, .45); }
.store:active { transform: translateY(1px); }
.store svg { flex: none; }
.store-txt { display: grid; line-height: 1.12; text-align: left; }
.store-txt small { font-size: .68rem; font-weight: 500; opacity: .72; letter-spacing: .01em; }
.store-txt b { font-size: 1.07rem; font-weight: 700; letter-spacing: -.02em; }

/* The Android counterpart. Deliberately NOT a Play badge: the app is not on
   Play yet, and a badge that looks like a download but is not one is the
   fastest way to lose somebody on their first visit. */
.store-soon {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  padding: 11px 22px 11px 18px;
  border-radius: 14px;
  background: transparent;
  border: 1px dashed #c0c8d4;
  color: var(--muted);
  text-decoration: none;
  transition: border-color .14s ease, color .14s ease;
}
.store-soon:hover { border-color: #97a2b2; color: var(--text); }
.store-soon svg { flex: none; }

/* ----------------------------------------------------------------- cards */

.card {
  background: linear-gradient(180deg, #ffffff 0%, #fbfcfd 100%);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--card-shadow);
  padding: var(--s5);
}

/* A card that names one of the two people takes a hairline of their colour
   along the top edge, which is how the app already distinguishes them. */
.card-me      { border-top-color: color-mix(in srgb, var(--me) 55%, var(--border-soft)); }
.card-partner { border-top-color: color-mix(in srgb, var(--partner) 55%, var(--border-soft)); }

.grid { display: grid; gap: var(--s4); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

@media (max-width: 860px) {
  .grid-2, .grid-3 { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------------------- devices */

/* A phone frame rather than a bare screenshot. The bezel is what stops a
   light screenshot from reading as a white rectangle pasted on the page. */
.phone {
  position: relative;
  width: 100%;
  max-width: 312px;
  aspect-ratio: 1320 / 2868;
  margin-inline: auto;
  padding: 9px;
  border-radius: 46px;
  background: linear-gradient(160deg, #2b313b 0%, #12151a 46%, #262c36 100%);
  box-shadow: var(--float), 0 0 0 1px rgba(255, 255, 255, .06);
}
.phone img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  border-radius: 38px;
  background: #f5f7fa;
}
/* The speaker slot. One small physical detail is enough to sell the frame. */
.phone::after {
  content: "";
  position: absolute;
  top: 20px; left: 50%;
  translate: -50% 0;
  width: 74px; height: 6px;
  border-radius: 999px;
  background: #0b0d11;
  opacity: .82;
}

.phone-sm { max-width: 250px; border-radius: 40px; padding: 8px; }
.phone-sm img { border-radius: 33px; }
.phone-sm::after { width: 60px; height: 5px; top: 17px; }

/* ------------------------------------------------------------- the media */

/* The alternating feature row: copy one side, phone the other. */
.media {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(var(--s5), 6vw, var(--s8));
  align-items: center;
}
.media.flip > .media-shot { order: -1; }
@media (max-width: 860px) {
  .media { grid-template-columns: minmax(0, 1fr); gap: var(--s6); }
  .media.flip > .media-shot { order: 0; }
}

.media-copy { display: grid; gap: var(--s3); align-content: start; }

/* ----------------------------------------------------------------- lists */

.ticks { display: grid; gap: 13px; margin: 0; padding: 0; list-style: none; }
.ticks li {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr);
  gap: 12px;
  align-items: start;
  color: var(--muted);
}
.ticks li b { color: var(--text); font-weight: 600; }
.tick {
  width: 22px; height: 22px;
  margin-top: 1px;
  border-radius: 999px;
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--accent) 20%, transparent);
  color: var(--accent-ink);
  flex: none;
}

/* --------------------------------------------------------------- the nav */

.nav {
  position: sticky;
  top: 0;
  z-index: 40;
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(14px) saturate(1.4);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  border-bottom: 1px solid transparent;
  transition: border-color .2s ease, background-color .2s ease;
}
.nav.stuck { border-bottom-color: var(--border-soft); }

.nav-in {
  display: flex;
  align-items: center;
  gap: var(--s4);
  min-height: 68px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  font-weight: 800;
  font-size: 1.12rem;
  letter-spacing: -.02em;
  margin-right: auto;
}
.brand img { width: 30px; height: 30px; }

.nav-links { display: flex; align-items: center; gap: var(--s1); }
.nav-links a {
  padding: 8px 14px;
  border-radius: var(--radius-pill);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--muted);
  text-decoration: none;
  transition: color .14s ease, background-color .14s ease;
}
.nav-links a:hover { color: var(--text); background: rgba(17, 19, 24, .05); }
.nav-links a[aria-current="page"] { color: var(--text); background: rgba(17, 19, 24, .07); }

@media (max-width: 760px) {
  .nav-links { display: none; }
}

/* ------------------------------------------------------------- the ring */

/* The mark is two arcs closing into one ring, and that is the site's whole
   structural idea, so it gets drawn full size behind the hero rather than
   only sitting in the corner as a logo. */
.ring-bed {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
  z-index: 0;
}
/* Sized off the column gap, not a percentage of the column alone. At 150% it
   reached across the gap and drew straight through the paragraph at mid
   widths (visible at 1000px). The ring may spill into the gap on each side
   but never past it: diameter <= column + 2 x gap, with a margin to spare. */
.ring-bed svg { width: calc(100% + 1.4 * clamp(32px, 5vw, 96px)); height: auto; overflow: visible; }

.ring-arc {
  fill: none;
  stroke-width: 1.15;
  stroke-linecap: round;
  /* Faint on purpose. It is the ground the product sits in, not a graphic
     competing with it. At full strength it read as a hard stroke drawn over
     the page rather than behind it. */
  opacity: .5;
}
.ring-arc-me { stroke: var(--me); }
.ring-arc-partner { stroke: var(--partner); }

/* Drawn closed on load: cobalt down one side, coral up the other, meeting.
   The product thesis as a gesture, and it costs two keyframes. */
@media (prefers-reduced-motion: no-preference) {
  .ring-arc {
    stroke-dasharray: 126;
    stroke-dashoffset: 126;
    animation: ring-close 1.5s cubic-bezier(.22, .61, .36, 1) .15s forwards;
  }
  .ring-arc-partner { animation-delay: .28s; }
}
@keyframes ring-close { to { stroke-dashoffset: 0; } }

/* ---------------------------------------------------------------- footer */

.footer {
  border-top: 1px solid var(--border);
  background: #eef1f5;
  padding-block: var(--s7) var(--s6);
}
.footer-grid {
  display: grid;
  grid-template-columns: 1.6fr repeat(3, minmax(0, 1fr));
  gap: var(--s5);
}
@media (max-width: 760px) {
  .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .footer-brand { grid-column: 1 / -1; }
}
.footer h4 {
  font-size: var(--t-label);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
  font-weight: 700;
  margin-bottom: 14px;
}
.footer-links { display: grid; gap: 10px; }
.footer-links a {
  color: var(--muted);
  text-decoration: none;
  font-size: var(--t-sm);
  width: fit-content;
  transition: color .14s ease;
}
.footer-links a:hover { color: var(--text); }
.footer-base {
  margin-top: var(--s6);
  padding-top: var(--s4);
  border-top: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
  align-items: center;
  justify-content: space-between;
  color: var(--dim);
  font-size: var(--t-sm);
}

/* ------------------------------------------------------------------- faq */

/* Shared, because three pages use it. This lived in the home page's own style
   block to begin with, which meant every other page asking for .faq got the
   browser's default disclosure triangles and no spacing. */
.faq { display: grid; gap: 0; border-top: 1px solid var(--border-soft); max-width: 78ch; }
.faq details { border-bottom: 1px solid var(--border-soft); }
.faq summary {
  cursor: pointer;
  list-style: none;
  padding: 22px 44px 22px 0;
  font-weight: 700;
  font-size: 1.06rem;
  letter-spacing: -.015em;
  position: relative;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::marker { content: ""; }
/* A chevron that rotates rather than a plus that swaps glyph, so the open and
   closed states are the same object in two positions. */
.faq summary::after {
  content: "";
  position: absolute;
  right: 8px; top: 50%;
  width: 11px; height: 11px;
  border-right: 2px solid var(--muted);
  border-bottom: 2px solid var(--muted);
  translate: 0 -60%;
  rotate: 45deg;
  transition: rotate .18s ease, border-color .18s ease;
}
.faq details[open] summary::after { rotate: -135deg; border-color: var(--accent-ink); }
.faq summary:hover::after { border-color: var(--text); }
.faq-a { padding: 0 44px 24px 0; color: var(--muted); max-width: 68ch; }
.faq-a a { color: var(--accent-ink); }

/* ------------------------------------------------------------------ misc */

/* A chip that states a fact about availability. Amber is the app's one
   caution hue and is the honest colour for "not yet". */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  font-size: var(--t-label);
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  border: 1px solid var(--border);
  color: var(--muted);
  background: var(--panel);
  width: fit-content;
}
.chip-live { color: var(--accent-ink); border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.chip-soon { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 34%, transparent); }

.dot {
  width: 7px; height: 7px;
  border-radius: 999px;
  background: currentColor;
  flex: none;
}

.center { text-align: center; }
.stack { display: grid; gap: var(--s4); }
.row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.row-center { justify-content: center; }
.mx-auto { margin-inline: auto; }
.maxw-60 { max-width: 60ch; }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* Skip link, visible the moment it takes focus. */
.skip {
  position: absolute; left: var(--s4); top: -60px;
  z-index: 100;
  padding: 10px 18px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 700;
  text-decoration: none;
  transition: top .18s ease;
}
.skip:focus { top: 12px; }

/* ---------------------------------------------------------- launch switch */

/* Unio is not on the App Store yet, so anything that would send somebody to a
   store listing is marked .post-launch and hidden, and the waitlist is marked
   .pre-launch. A store button that opens "this app is not available" loses the
   visit; a list keeps it.
   LAUNCH DAY: swap which of these two classes is hidden. The Android list on
   android.html is not marked either way, because it outlives the iOS launch. */
.post-launch { display: none !important; }
.pre-launch { }

/* --------------------------------------------------------------- waitlist */

.waitlist { display: grid; gap: 12px; width: 100%; max-width: 480px; }

/* iPhone or Android, as a segmented control rather than a dropdown: two
   options, both visible, one tap. */
.waitlist-plat {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  border-radius: var(--radius-pill);
  background: var(--panel-2);
  width: fit-content;
}
.waitlist-plat label {
  position: relative;
  padding: 7px 16px;
  border-radius: var(--radius-pill);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  transition: background-color .14s ease, color .14s ease, box-shadow .14s ease;
}
.waitlist-plat input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.waitlist-plat label:has(input:checked) { background: var(--panel); color: var(--text); box-shadow: var(--card-shadow); }
.waitlist-plat label:has(input:focus-visible) { outline: 2px solid var(--accent-ink); outline-offset: 2px; }

.waitlist-row { display: flex; gap: 8px; }
.waitlist-row input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 14px 20px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text);
  font: inherit;
  font-size: var(--t-body);
  transition: border-color .14s ease, box-shadow .14s ease;
}
.waitlist-row input::placeholder { color: var(--dim); }
.waitlist-row input:focus {
  outline: none;
  border-color: var(--accent-ink);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 28%, transparent);
}
.waitlist-row .btn { flex: none; }
.waitlist-row .btn:disabled { opacity: .6; cursor: progress; }

.waitlist-msg { font-size: var(--t-sm); color: var(--muted); min-height: 1.4em; }
.waitlist-msg[data-tone="bad"] { color: var(--danger); }
.waitlist-msg[data-tone="ok"] { color: var(--accent-ink); font-weight: 600; }
.waitlist.is-done .waitlist-row,
.waitlist.is-done .waitlist-plat { display: none; }

/* Honeypot: present in the markup, invisible to people, filled in by bots. */
.wl-hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }

/* Centred wherever the surrounding block is centred. */
.waitlist.is-centered { margin-inline: auto; justify-items: center; text-align: center; }

@media (max-width: 480px) {
  .waitlist-row { flex-direction: column; }
  .waitlist-row .btn { width: 100%; }
}

/* ------------------------------------------------------------ slim chrome */

/* The one page site has a logo and a single button in the nav, and a one line
   footer. Shared so support.html matches the home page. */
.nav-in { justify-content: space-between; }
.foot { padding-block: var(--s6); border-top: 1px solid var(--border); background: var(--bg); }
.foot-in { display: flex; flex-wrap: wrap; gap: var(--s3) var(--s5); align-items: center; justify-content: space-between;
           color: var(--dim); font-size: var(--t-sm); }
.foot-links { display: flex; gap: var(--s4); flex-wrap: wrap; }
.foot-links a { color: var(--muted); text-decoration: none; }
.foot-links a:hover { color: var(--text); }
