/* Hueo — shared stylesheet for every page of the site.
   The page background is a single flat color, the way the app fills the screen
   with one color: `--page` is repainted by the swatch strip on the home page,
   and `--on-page` is the text color that sits directly on it — plain white on
   dark colors, plain black on light ones, decided by luminance in site.js the
   way the app decides its own text color. Everything else lives inside translucent white cards. */

:root {
  /* Rosco 3202 Full CTB, the site's resting --page color: titles and links
     carry the color the site opens on. */
  --accent: #6a81ff;
  /* --accent fails AA as text (3.4:1 on white, 2.7:1 on the card over a dark page);
     --accent-ink is the same hue darkened to ~5.8:1 and is what text uses. --accent stays
     for icons and focus outlines, where 3:1 is enough. */
  --accent-ink: #4358d8;
  --ink: #333;
  --muted: #5c5c61;
  --page: rgb(106, 129, 255);
  /* Matches the default --page (Full CTB): site.js recomputes both on every
     color change, this pair is only what a no-JavaScript visit gets. */
  --on-page: #fff;
  --halo: rgba(255, 255, 255, 0.28);
  --card: rgba(255, 255, 255, 0.9);
  --line: #ececf0;
  --shadow: 0 4px 12px rgba(0, 0, 0, 0.14);
}

* { box-sizing: border-box; }

body {
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  margin: 40px;
  background-color: var(--page);
  color: var(--ink);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  transition: background-color 0.45s ease;
}

a {
  color: var(--accent-ink);
  font-weight: 700;
  text-decoration: none;
}

.container {
  max-width: 860px;
  margin: auto;
}

.container.narrow { max-width: 680px; }

.card {
  background: var(--card);
  padding: 30px;
  border-radius: 14px;
  box-shadow: var(--shadow);
  margin-bottom: 22px;
  backdrop-filter: saturate(120%);
  -webkit-backdrop-filter: saturate(120%);
}

h1 {
  color: var(--accent-ink);
}

h2 {
  color: var(--accent-ink);
  font-size: 1.15em;
  margin-top: 1.8em;
}

/* Headings that sit on the page color instead of inside a card. */
.section-title {
  color: var(--on-page);
  font-size: 1.3em;
  margin: 34px 0 18px;
  transition: color 0.45s ease;
}

.subtitle {
  font-weight: bold;
  margin-top: -0.5em;
}

.effective {
  color: var(--muted);
  font-size: 0.9em;
}

li { margin-bottom: 0.4em; }

/* Assembled by site.js — see revealMail(). It is a link only once the script
   has run, so it is styled like one from the start. */
.mail {
  color: var(--accent-ink);
  cursor: pointer;
  word-break: break-word;
}

/* Running text in the cards is justified; hyphenation keeps the word spacing from
   opening up on a narrow column. */
.card p,
.card li {
  text-align: justify;
  hyphens: auto;
  -webkit-hyphens: auto;
}

/* ---------- nav ---------- */
.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 22px;
}

.nav img {
  display: block;
  /* hueo-logo.png is 102px tall: about 2x at this size. */
  height: 52px;
  width: auto;
  /* A soft white glow behind the wordmark, the same on every page color. */
  filter: drop-shadow(0 0 20px var(--halo));
}

.nav-links a {
  margin-left: 18px;
  font-size: 0.95em;
  color: var(--on-page);
  font-weight: 700;
  transition: color 0.45s ease;
}

.nav-links a:first-child { margin-left: 0; }

/* The home page's hero phone sticks out above its card, so the nav needs more
   clearance there than on the text pages. */
.home .nav { margin-bottom: 76px; }

/* ---------- hero ---------- */
.hero {
  padding-bottom: 0;
  /* Not `overflow: hidden` any more: the phone deliberately sticks out above
     the card. The rounded bottom corners the card used to clip are now cut by
     the swatch strip itself, which is the element that reaches the edges. */
  overflow: visible;
}

.hero-top {
  display: flex;
  align-items: flex-start;
  gap: 30px;
  margin-bottom: 10px;
}

.hero-copy {
  flex: 1 1 auto;
  min-width: 0;
}

.hero-shot {
  flex: 0 0 232px;
  /* Out of the top of the card, and just over the swatch strip below it. The
     home page's nav carries extra bottom margin (.home .nav) to leave room. */
  margin: -56px 0 -34px;
  position: relative;
  z-index: 2;
  /* The phone lies over the last swatches of the strip; it is decoration, so
     clicks must reach the buttons underneath it. */
  pointer-events: none;
}

/* ---------- device frames ---------- */
/* The frame is sized in container-width units, so a phone keeps the exact same
   proportions at any size: 232px is the hero phone, where the border is 5px,
   the outer radius 28px and the inner one 23px. The px values are the fallback
   for a browser without container query units. */
.hero-shot,
.shots li { container-type: inline-size; }

.phone {
  display: block;
  border: 5px solid #1c1c1e;
  border: 2.155cqw solid #1c1c1e;
  border-radius: 28px;
  border-radius: 12.07cqw;
  background: #1c1c1e;
  overflow: hidden;
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.22);
}

.phone img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 23px;
  border-radius: 9.91cqw;
}

.shots {
  display: flex;
  flex-wrap: nowrap;
  gap: 24px;
  /* One row, full viewport width: break out of the 860px column and scroll
     sideways. The first phone lines up with the column's left edge. */
  margin: 0 calc(50% - 50vw) 22px;
  padding: 0 max(16px, calc(50vw - 430px)) 14px;
  overflow-x: auto;
  scroll-padding: 0 max(16px, calc(50vw - 430px));
  scrollbar-width: none;
  list-style: none;
}

.shots::-webkit-scrollbar { display: none; }

.shots li { flex: 0 0 230px; }

.shots figure { margin: 0; }

.shots figcaption {
  margin-top: 12px;
  text-align: center;
  font-size: 0.88em;
  color: var(--on-page);
  transition: color 0.45s ease;
}

.shots figcaption b { display: block; }

.shots figcaption span { display: block; margin-top: 2px; opacity: 0.85; }

.hero h1 {
  font-size: 2.35em;
  line-height: 1.15;
  margin: 0 0 12px;
  letter-spacing: -0.02em;
}

.lede {
  font-size: 1.12em;
  color: var(--muted);
  margin: 0 0 22px;
  max-width: 34em;
}

.soon {
  font-size: 0.88em;
  color: var(--muted);
  margin: 0;
}

.badges {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 14px;
}

.badge-link {
  display: inline-block;
  line-height: 0;
}

.badge-link:hover {
  text-decoration: none;
  opacity: 0.85;
}

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

/* The Play badge until the listing is live: present at full size so the row
   does not reflow when it becomes a real link, but visibly inert — dimmed, no
   pointer cursor, no hover response, and not focusable, because it is a <span>
   and not an <a>. The "Coming soon" caption is what says so in words; the
   accessible name on the <span> repeats it, since the caption is aria-hidden to
   avoid the screen reader announcing the same thing twice. */
.badge-link.is-disabled {
  cursor: default;
  text-align: center;
}

.badge-link.is-disabled:hover { opacity: 1; }

/* Google ships the generic badge with transparent clear space baked into the
   file: of its 646x250 canvas, the artwork occupies the middle 67.2% vertically
   and 87.3% horizontally (measured on the asset, not estimated). Apple's SVG is
   cropped tight instead, so at an equal CSS height Google's renders a third
   smaller. 80px here makes the visible artwork 80 * 0.672 = 54px, exactly the
   height of the Apple badge next to it, and the -13px vertical margin (0.164 *
   80) folds the transparent padding back out of the layout box so both badges
   occupy the same 54px and align top and bottom. The horizontal padding is left
   alone: it is Google's required clear space, and here it only widens the gap to
   the badge beside it. */
.badge-link.is-disabled img {
  height: 80px;
  margin: -13px 0;
  opacity: 0.55;
  filter: grayscale(100%);
}

.badge-soon {
  display: block;
  margin-top: 4px;
  font-size: 0.72em;
  line-height: 1.4;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.cta-note {
  font-size: 0.88em;
  color: var(--muted);
  margin: 14px 0 4px;
}

/* ---------- swatch strip ---------- */
.swatches {
  display: flex;
  margin: 0 -30px;
  height: 78px;
  overflow: hidden;
}

/* Twice the strip's width: two copies of the gels, moved by site.js. */
.swatch-track {
  display: flex;
  flex: none;
  width: 200%;
  height: 100%;
  will-change: transform;
}

.swatches button {
  flex: 1;
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: flex 0.25s ease;
  font: inherit;
}

.swatches button:hover,
.swatches button:focus-visible { flex: 1.7; }

/* A visible keyboard focus ring everywhere. The swatches and the presets used
   to set `outline: none`, which left keyboard users with no idea where they
   were: the strip only grew the focused swatch, and that reads as a hover
   effect, not as focus. */
:focus-visible {
  outline: 3px solid var(--on-page);
  outline-offset: 3px;
  border-radius: 4px;
}

.card :focus-visible,
.swatches button:focus-visible {
  outline-color: var(--accent);
}

.swatches button:focus-visible { outline-offset: -3px; }

.swatch-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  font-size: 0.85em;
  color: var(--muted);
  padding: 12px 30px 16px;
  margin: 0 -30px;
  border-top: 1px solid var(--line);
}

.swatch-label b { color: var(--ink); }

/* ---------- feature cards ---------- */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 22px;
}

.grid .card {
  margin-bottom: 0;
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 12px;
  align-items: center;
  align-content: start;
}

.grid .card > p { grid-column: 1 / -1; }

.grid h3 {
  margin: 0 0 8px;
  font-size: 1.05em;
}

/* Icon and title share a row: the bottom margin of both is what keeps the text
   below at the same distance as before. */

.grid p {
  margin: 0;
  color: var(--muted);
  font-size: 0.95em;
}

.icon {
  display: block;
  margin-bottom: 8px;
  color: var(--accent);
}

.pro {
  display: inline-block;
  font-size: 0.68em;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-ink);
  border: 1px solid rgba(0, 122, 255, 0.35);
  border-radius: 999px;
  padding: 1px 8px;
  margin-left: 6px;
  vertical-align: 2px;
  font-weight: bold;
}

/* ---------- kelvin scale ---------- */
.kelvin {
  height: 46px;
  border-radius: 12px;
  margin: 18px 0 8px;
  border: 1px solid var(--line);
  background: linear-gradient(to right,
    rgb(255, 68, 0) 0%, rgb(255, 137, 14) 14%, rgb(255, 184, 123) 29%,
    rgb(255, 213, 179) 43%, rgb(255, 239, 225) 57%, rgb(255, 254, 250) 71%,
    rgb(221, 230, 255) 86%, rgb(202, 218, 255) 100%);
}

.scale {
  display: flex;
  justify-content: space-between;
  font-size: 0.82em;
  color: var(--muted);
}

/* ---------- CCT presets ---------- */
.presets {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  margin: 22px 0 0;
  padding: 0;
  list-style: none;
}

.presets > li { flex: 1 1 110px; }

.preset {
  width: 100%;
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  text-align: center;
  cursor: pointer;
  color: inherit;
}

.preset .dot {
  width: 50px;
  height: 50px;
  margin: 0 auto 8px;
  border-radius: 50%;
  border: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #6a5a48;
  transition: transform 0.2s ease;
}

.preset:hover .dot,
.preset:focus-visible .dot { transform: scale(1.07); }

.preset b {
  display: block;
  font-size: 0.95em;
}

.preset .kelvin-value {
  display: block;
  font-size: 0.85em;
  color: var(--muted);
}

/* ---------- facts ---------- */
.facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px 22px;
  text-align: center;
}

.facts b {
  display: block;
  color: var(--accent-ink);
  font-size: 1.7em;
  line-height: 1.2;
}

.facts span {
  font-size: 0.88em;
  color: var(--muted);
}

/* ---------- pricing ---------- */
.plan {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 14px;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}

.plan:last-of-type { border-bottom: 0; }

.plan span {
  color: var(--muted);
  font-size: 0.92em;
}

.fine {
  font-size: 0.88em;
  color: var(--muted);
}

.flush-top { margin-top: 0; }
.flush-bottom { margin-bottom: 0; }
.flush { margin: 0; }

/* ---------- footer ---------- */
footer {
  text-align: center;
  color: var(--on-page);
  font-size: 0.88em;
  padding: 8px 0 20px;
  transition: color 0.45s ease;
}

footer a {
  color: var(--on-page);
  margin: 0 8px;
}

footer p:last-child { font-size: 0.86em; opacity: 0.65; }

footer a.credit { margin: 0; }

/* Full-screen toggle, built by site.js — the app's HideButton: 50px round, 26px
   from the right and 40px from the bottom. Shown interface: filled with the
   page color, a soft shadow, opacity 0.95. Hidden interface: no fill, no
   shadow, opacity 0.3, so only the color is left on screen. */
.ui-toggle {
  position: fixed;
  right: 26px;
  bottom: 40px;
  z-index: 999;
  width: 50px;
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background-color: var(--page);
  color: var(--on-page);
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.4);
  opacity: 0.95;
  cursor: pointer;
  transition: background-color 0.45s ease, color 0.45s ease, box-shadow 0.3s ease,
    opacity 0.3s ease, transform 0.1s ease;
}

.ui-toggle:active { transform: scale(1.06); }

.ui-toggle:focus-visible {
  outline: 3px solid var(--on-page);
  outline-offset: 3px;
}

.ui-hidden .ui-toggle {
  background-color: transparent;
  box-shadow: none;
  opacity: 0.3;
}

.ui-hidden .ui-toggle:hover,
.ui-hidden .ui-toggle:focus-visible { opacity: 0.6; }

/* "Press me" above the toggle, on every screen size: the text on top, an arrow
   below it pointing straight down. The hint is 90px wide and centred on the
   button (26px from the edge + 25px radius = 51px). No background, by choice: a soft shadow on the text and
   the arrow (drop-shadow follows both shapes) keeps it apart from whatever
   scrolls underneath. Removed by site.js on the first press. */
.ui-hint {
  position: fixed;
  right: 6px;
  bottom: 104px;
  width: 90px;
  z-index: 998;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  /* Fixed white with a dark outline and a wide shadow, rather than --on-page:
     on a narrow screen the hint lies over the white cards as well as the page
     color, and white-on-white vanished. The outline keeps it readable on both,
     and still no box behind it. */
  color: #fff;
  filter: drop-shadow(0 0 1.5px rgba(0, 0, 0, 0.75)) drop-shadow(0 0 1.5px rgba(0, 0, 0, 0.45))
    drop-shadow(0 2px 8px rgba(0, 0, 0, 0.25));
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  font-weight: 700;
  font-size: 1.05rem;
  pointer-events: none;
  animation: ui-hint-bob 1.6s ease-in-out infinite;
}

.ui-hint span { white-space: nowrap; }
.ui-hint svg { display: none; }
.ui-hint svg.ui-hint-down { display: block; }

@keyframes ui-hint-bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(5px); }
}

body > :not(.ui-toggle) { transition: opacity 0.3s ease, visibility 0.3s; }

.ui-hidden body > :not(.ui-toggle) {
  opacity: 0;
  visibility: hidden;
}

/* Everything on this site that moves is decoration: the color cross-fade, the
   swatch that widens, the preset that zooms. None of it carries meaning, so it
   all goes away when the visitor asks for less motion. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }

  .swatches button:hover,
  .swatches button:focus-visible { flex: 1; }

  .preset:hover .dot,
  .preset:focus-visible .dot { transform: none; }
}

/* Visible only to screen readers. */
.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;
}

.heart {
  /* Same ink as the footer text it sits in — which flips with the page color,
     so the heart follows it instead of staying a fixed pink. */
  vertical-align: -2px;
  color: currentColor;
}

/* ---------- skip link ---------- */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--card);
  color: var(--accent-ink);
  padding: 10px 16px;
  border-radius: 8px;
  z-index: 10;
}

.skip-link:focus {
  left: 8px;
  top: 8px;
}

@media (max-width: 760px) {
  /* The phone comes first here, then the copy, then the swatch strip. It is
     cropped to the top half of the screenshot and fades out at the bottom, so
     the crop line melts into the card instead of cutting into the text. */
  .hero-top {
    flex-direction: column;
    align-items: center;
    gap: 0;
    margin-bottom: 20px;
  }

  .hero-shot {
    order: -1;
    flex: none;
    align-self: center;
    /* Narrower than the card so the frame reads as a phone, not a banner.
       The ratio is the screenshot's own, halved (2532 / 2 = 1266), so exactly
       the top half of the interface shows however wide the screen is. */
    width: 78%;
    aspect-ratio: 1170 / 1266;
    /* 12px from the card's top edge, the same gap as between the logo and
       the menu: the negative margin takes back part of the card's 30px
       padding (22px below 640px, see there). */
    margin: -56px 0 6px;
    overflow: hidden;
    -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent);
    mask-image: linear-gradient(to bottom, #000 62%, transparent);
  }

  /* The crop box would cut the phone's shadow off in a grey rectangle behind the
     rounded corners, so there is none here. */
  .hero-shot .phone {
    box-shadow: none;
    border-bottom: 0;
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
  }

  .hero-shot .phone img {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
  }

  /* Room for the phone, which sticks 26px out of the top of the card. */
  .home .nav { margin-bottom: 48px; }
}

@media (max-width: 640px) {
  body { margin: 16px; }
  .card { padding: 22px; }
  .hero-shot { margin-top: -48px; }
  .hero h1 { font-size: 1.85em; }
  /* Both badges on one row at phone width, sized to fit it rather than
     wrapping. --badge-h is the visible artwork height of each badge: at most
     48px, shrinking with the viewport. The row is 3h wide for Apple (120x40
     artwork), 3.36h for Google's visible artwork, plus the 10px gap, inside
     the 16px body margin and 22px card padding on each side — hence
     (100vw - 86px) / 6.6.
     The Play badge is drawn on a canvas 1/0.672 of its artwork height, and
     its transparent clear space is the same 0.164 of canvas height on all
     four sides (Google's 646x250 file: 87.3% of the width, 67.2% of the
     height). That is 0.244h, folded back out on every side so the two badges
     sit flush. Without the more specific rule the Play badge would keep its
     desktop size. */
  .badges {
    --badge-h: min(48px, calc((100vw - 86px) / 6.6));
    flex-wrap: nowrap;
    justify-content: center;
    gap: 10px;
  }
  .badge-link img { height: var(--badge-h); }
  .badge-link.is-disabled img {
    height: calc(var(--badge-h) / 0.672);
    margin: calc(var(--badge-h) * -0.244);
  }
  .facts { gap: 10px; }

  /* Logo and menu always on one row. */
  .nav { flex-wrap: nowrap; gap: 10px; }
  .nav img { height: 40px; }
  .nav-links { white-space: nowrap; }
  .nav-links a { margin-left: 12px; font-size: 0.85em; }

  .swatches { margin: 0 -22px; height: 60px; }
  .swatch-label { margin: 0 -22px; padding: 12px 22px 16px; }
  /* All three screenshots in a sideways scroller, about two and a third in
     view, so the cut third says "there is more". It runs to the edges of the
     screen (undoing the 16px body margin) and snaps to each phone. */
  .shots {
    display: flex;
    flex-wrap: nowrap;
    justify-content: flex-start;
    gap: 16px;
    margin: 0 -16px 22px;
    padding: 0 16px 6px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding: 0 16px;
    scrollbar-width: none;
  }
  .shots::-webkit-scrollbar { display: none; }
  .shots li {
    flex: 0 0 calc((100% - 2 * 16px) / 2.3);
    scroll-snap-align: start;
  }
}

@media (max-width: 360px) {
  .nav img { height: 34px; }
  .nav-links a { margin-left: 9px; font-size: 0.8em; }
}

/* Menu links scroll smoothly to their section and stop a little below the top
   edge. Not for visitors who asked for reduced motion. */
html { scroll-behavior: smooth; }
[id="features"], [id="pro"] { scroll-margin-top: 24px; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}
