/* ==========================================================================
   ALLiN marketing site, shared stylesheet.
   Design language extracted from the ALLiN app. Every page loads this file.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens
   -------------------------------------------------------------------------- */
:root {
  /* Background system.
     ⚠️ LIFTED FROM THE APP, DO NOT RE-EYEBALL. These are `Gradients.appBackground`
     and `AppBackgroundGeometry` in src/constants/theme.ts. The app re-graded to a
     DIAGONAL purple ramp on 2026-08-10 and this file was still carrying the
     retired vertical blue-violet "northern lights", which is why the site read
     blue-teal while every app screenshot pasted onto it read pink-purple. The
     hues there were measured against the user's reference photo and approved;
     copying them is the whole point, so change them in theme.ts or not at all. */
  --bg: #0A0714;               /* app `background`, the page base */
  --bg-deep: #060309;          /* the ramp's terminal stop, for deep sections */
  --aurora-1: #B44FE6;         /* pink-purple, lands in the TOP-RIGHT corner */
  --aurora-2: #5F1EA8;         /* 44% */
  --aurora-3: #240B59;         /* 76%, indigo heading to the bottom-left */

  /* Surfaces */
  --card: #120D20;
  --card-border: #2A2142;
  --elevated: #191231;
  --radius-card: 26px;

  /* Text */
  --text: #EAE9F2;             /* off-white, never pure #FFF for body */
  --text-2: #ABA8C0;           /* secondary */
  /* ⚠️ BRIGHTER THAN THE APP'S `textMuted` (#6E6A85) ON PURPOSE. That value is a
     label tier next to an icon on a phone held at arm's length; here it was
     carrying real prose (the about/support paragraphs, the legal effective
     dates, every footer column heading) at 3.5:1, i.e. under AA. This clears
     4.5:1 on every surface in this file, including --elevated. */
  --text-3: #8B87A3;           /* muted, still clearly the third tier */

  /* Brand green, used sparingly */
  --green: #28E693;
  --green-deep: #0FBE77;
  --cta-grad-1: #57F2B2;
  --cta-grad-2: #0FBE77;
  --cta-text: #06231A;

  /* Panic red, the one loud thing */
  --red: #FF2A2A;
  --red-grad-1: #FF5A5A;
  --red-grad-2: #E00A0A;

  /* Accents, one per concept */
  --blue: #3FC0F5;
  --purple: #A96BFF;
  --orange: #FFA845;
  --coral: #FF6E5C;
  --teal: #2FD8C2;
  --yellow: #FFD042;
  --pink: #FF88C4;
  --cobalt: #2E63DE;
  --block-content: #F42B20;
  --block-place: #FF9124;

  /* Secondary control surface: ghost buttons, the legal switcher pills, the
     store badges and the notify input.
     ⚠️ OPAQUE, NOT A WHITE WASH. These used to be `rgba(234,233,242,0.06)`,
     which means the control has no colour of its own: over the near-black
     sections it is a faint smudge and over the bright top-right of the aurora
     it all but disappears, so the same button looked like two different
     components on one page. That see-through chrome is exactly the "washed out
     and transparent" note the app kept getting. An opaque surface reads as the
     same object wherever it lands, and it is what the app does: near-black
     chips on the purple field.
     ⚠️ THE BORDER, NOT THE FILL, IS WHAT CARRIES IT ON THE DEEP SECTIONS.
     --elevated over --bg-deep is only 1.14:1, so the outline has to do the
     work there: this mix measures 3.29:1 against --bg-deep, clearing the 3:1
     that a UI component boundary needs. --card-border alone was 1.36:1. */
  --chip: var(--elevated);
  --chip-hover: #221838;
  --chip-border: color-mix(in srgb, var(--text) 30%, var(--card-border));

  /* Layout */
  --maxw: 1120px;
  --gutter: clamp(20px, 4vw, 32px);
  --header-h: 84px;

  /* Type */
  --font: "Nunito Sans", "Avenir Next", "Segoe UI", system-ui, -apple-system, sans-serif;

  /* Default accent for fade cards and glows */
  --accent: var(--green);
}

/* --------------------------------------------------------------------------
   2. Reset + base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 16px);
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--font);
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--text);
  background-color: var(--bg);
  min-height: 100vh;
  overflow-x: hidden;
}

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

a { color: inherit; }

button { font-family: inherit; }

::selection { background: rgba(40, 230, 147, 0.28); color: var(--text); }

.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;
}

/* --------------------------------------------------------------------------
   3. Aurora background
   The app's signature field, ported from GemAtmosphere's AURORA_GLOWS.

   ⚠️ THE DIRECTION IS THE DESIGN. Stop 1 sits in the TOP-RIGHT corner and the
   ramp runs diagonally down to the bottom-left. Drawn vertically (which is what
   this file used to do) the pink smears across the whole top edge and the page
   reads "pink" instead of "pink corner over an indigo field" — the exact note
   the user kept giving on the app until it was re-graded.

   ⚠️ THE GLOWS ONLY REINFORCE THE RAMP'S TWO ENDS. They used to do all the work,
   which is why chasing a pink corner with glow alpha kept turning everything
   pink: a vertical base cannot put anything in a corner.

   The band is a fixed height pinned to the top of the page rather than the whole
   scroll, so the long sections below rest on flat near-black and the cards pop.
   Applied to <body> via .has-aurora (the template sets it).
   -------------------------------------------------------------------------- */
.has-aurora {
  background-color: var(--bg);
  background-image:
    /* ⚠️ THE DISSOLVE, AND IT HAS TO BE FIRST (first layer = topmost). The band
       is a fixed height, but four of the glows below still carry alpha at its
       bottom edge (the two indigo fields and the two dark corner wraps), so the
       band stopped with a visible horizontal seam straight across the page.
       Resolving the last third to the page base kills it no matter what the
       layers underneath composite to. The rgba() is --bg with the alpha taken
       off, so the fade never drifts through a different hue on the way. */
    linear-gradient(180deg, rgba(10, 7, 20, 0) 60%, rgba(10, 7, 20, 1) 100%),
    /* pink — the whole top band, running straight down so the top-LEFT is lit
       too. A corner-anchored glow is already spent by the time it crosses to
       the other side, which is what leaves the upper left reading too dark. */
    linear-gradient(180deg, rgba(214, 96, 214, 0.13) 0%, rgba(214, 96, 214, 0) 70%),
    /* pink — extra warmth in the top-right corner itself */
    linear-gradient(215deg, rgba(236, 92, 196, 0.17) 0%, rgba(236, 92, 196, 0) 46%),
    /* indigo — the bottom-left field */
    linear-gradient(25deg, rgba(50, 26, 132, 0.46) 0%, rgba(50, 26, 132, 0) 72%),
    /* indigo — the left edge gets its own horizontal wash. The base runs
       corner to corner, so on a wide viewport the left edge would otherwise
       sit at nearly the same hue as the right. */
    linear-gradient(90deg, rgba(40, 18, 110, 0.50) 0%, rgba(40, 18, 110, 0) 70%),
    /* dark wraps settle the bottom corners onto near-black */
    linear-gradient(35deg, rgba(6, 3, 12, 0.58) 0%, rgba(6, 3, 12, 0) 60%),
    linear-gradient(325deg, rgba(6, 3, 12, 0.52) 0%, rgba(6, 3, 12, 0) 60%),
    /* The base ramp, top-right to bottom-left.
       ⚠️ THE STOPS ARE PULLED IN FROM THE APP'S [0, .44, .76, 1], and that is a
       correction, not a drift. The app paints one 430x932 screen, where a
       corner-to-corner axis is dominated by height and stop 1 stays a corner.
       A 1440x1080 band is landscape, so the same stops spread the bright
       pink-purple across half the page and it reads as a pink wash, which is
       the note the app itself spent three rounds fixing.
       ⚠️ IT MUST END ON --bg, NOT ON THE APP'S NEAR-BLACK. The band is a fixed
       height over a long scrolling page, so anything darker than the page base
       leaves a visible horizontal seam where the band stops. Ending on the base
       colour dissolves it. */
    linear-gradient(to bottom left,
      var(--aurora-1) 0%,
      var(--aurora-2) 30%,
      var(--aurora-3) 62%,
      var(--bg) 100%);
  background-repeat: no-repeat;
  background-size: 100% var(--aurora-h, 1080px);
  background-position: top center;
}

/* On a phone the band is much taller than it is wide, so the corner-to-corner
   axis is dominated by height and the pink never reaches across. Shortening it
   keeps the same picture in a portrait frame. */
@media (max-width: 760px) {
  .has-aurora { --aurora-h: 760px; }
}

/* --------------------------------------------------------------------------
   4. Type scale
   -------------------------------------------------------------------------- */
h1, h2, h3, h4 {
  line-height: 1.12;
  color: var(--text);
  text-wrap: balance;
}

h1 { font-size: clamp(2.5rem, 6.5vw, 4.1rem); font-weight: 900; letter-spacing: -0.015em; }
h2 { font-size: clamp(1.9rem, 4.2vw, 2.75rem); font-weight: 900; letter-spacing: -0.01em; }
h3 { font-size: clamp(1.25rem, 2.4vw, 1.5rem); font-weight: 800; }
h4 { font-size: 1.125rem; font-weight: 800; }

p { color: var(--text-2); }
p strong { color: var(--text); }

.lead {
  font-size: clamp(1.125rem, 2vw, 1.3rem);
  line-height: 1.55;
  color: var(--text-2);
  max-width: 42em;
}

/* Small uppercase kicker above headings */
.kicker {
  display: inline-block;
  font-size: 0.8125rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--green);
  margin-bottom: 14px;
}
.kicker--muted { color: var(--text-2); }

/* Preserve the ALLiN wordmark's exact casing inside uppercase kickers */
.keep-case { text-transform: none; }

/* Emerald number or phrase inside a heading */
.hl { color: var(--green); }

/* --------------------------------------------------------------------------
   5. Layout: container + section rhythm
   -------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: clamp(64px, 9vw, 112px); }
.section--tight { padding-block: clamp(40px, 6vw, 72px); }

/* Deeper sections rest on the near-black plum so cards pop */
.section--deep { background: var(--bg-deep); }

.section-head { max-width: 640px; margin-bottom: clamp(32px, 5vw, 56px); }
.section-head--center { margin-inline: auto; text-align: center; }
.section-head p { margin-top: 14px; }

/* --------------------------------------------------------------------------
   6. Cards
   -------------------------------------------------------------------------- */
.card {
  background: var(--card);
  border: 1px solid var(--card-border);
  border-radius: var(--radius-card);
  padding: clamp(20px, 3vw, 24px);
  transition: transform 220ms ease, border-color 220ms ease, box-shadow 220ms ease;
}
/* Quiet lift on pointer hover only; touch and reduced-motion users get none */
@media (hover: hover) {
  .card:hover {
    transform: translateY(-3px);
    border-color: color-mix(in srgb, var(--accent) 42%, var(--card-border));
    box-shadow: 0 14px 34px rgba(0, 0, 0, 0.35);
  }
}
@media (prefers-reduced-motion: reduce) {
  .card, .card:hover { transform: none; }
}

.card--elevated { background: var(--elevated); }

.card h3 + p, .card h4 + p { margin-top: 8px; }

/* Fade card: accent melting from 40% to 7% alpha over the near-black base,
   with a 50%-alpha accent border. Set the accent per card:
   <div class="card fade-card" style="--accent: var(--purple)"> or use an
   .accent-* helper class. */
/* ⚠️ THE WASH IS 18%, NOT 40%, AND THAT IS A CONTRAST FIX. A 40% accent behind
   --text-2 measured 2.81:1 on the yellow card, 3.06 on green and 3.21 on teal:
   five of the ten accents were under AA and the cards read exactly as "washed
   out and muddy". It is also not what the app does. App cards are near-black
   with a COLOURED ICON TILE on top; the colour identifies the card, it does not
   flood it. At 18% every accent clears 5.5:1 and the tint still reads. */
.fade-card {
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--accent) 18%, transparent),
      color-mix(in srgb, var(--accent) 4%, transparent)),
    var(--card);
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
}

/* ⚠️ THE MUTED TIER IS LIFTED ON TINTED SURFACES. --text-3 is set against the
   flat dark backgrounds, but a washed card or the calm band raises the
   luminance underneath it and the same grey falls back under AA (3.4:1 on the
   calm band's blue corner, 3.7:1 on the yellow card). This is scoped rather
   than global so the flat-dark pages keep their three distinct text tiers. */
.fade-card,
.calm-band { --text-3: #A6A2BC; }

/* Accent helpers, one concept per color */
.accent-green  { --accent: var(--green); }
.accent-blue   { --accent: var(--blue); }
.accent-purple { --accent: var(--purple); }
.accent-orange { --accent: var(--orange); }
.accent-coral  { --accent: var(--coral); }
.accent-teal   { --accent: var(--teal); }
.accent-yellow { --accent: var(--yellow); }
.accent-pink   { --accent: var(--pink); }
.accent-cobalt { --accent: var(--cobalt); --accent-text: #5B8CF0; }
.accent-red    { --accent: var(--red); --accent-text: #FF6B62; }

/* The two blockers, matching BlockerColor in the app's theme.ts. The content
   blocker used to be cobalt BLUE on this page, which matched nothing in the
   product; in the app it is the deep red of the pair, and the location blocker
   is the bright orange. */
.accent-blockcontent { --accent: var(--block-content); --accent-text: #FF6A5E; }
.accent-blockplace   { --accent: var(--block-place); }

/* Soft neon glow */
.glow { box-shadow: 0 0 20px color-mix(in srgb, var(--accent) 40%, transparent); }

/* Card grids */
.grid { display: grid; gap: clamp(16px, 2.5vw, 24px); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }

@media (max-width: 900px) {
  .grid--3, .grid--4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
  .grid--2, .grid--3, .grid--4 { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   7. Buttons (pills)
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 15px 28px;
  border-radius: 999px;
  border: 0;
  font-family: inherit;
  font-size: 1rem;
  font-weight: 800;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: transform 160ms ease, box-shadow 160ms ease, background-color 160ms ease;
}
.btn:active { transform: translateY(1px) scale(0.99); }

.btn--cta {
  background: linear-gradient(180deg, var(--cta-grad-1), var(--cta-grad-2));
  color: var(--cta-text);
  box-shadow: 0 0 20px rgba(40, 230, 147, 0.4);
}
.btn--cta:hover { box-shadow: 0 0 28px rgba(40, 230, 147, 0.55); transform: translateY(-1px); }

.btn--ghost {
  background: var(--chip);
  color: var(--text);
  border: 1px solid var(--chip-border);
}
.btn--ghost:hover { background: var(--chip-hover); border-color: var(--text-2); }

.btn--panic {
  background: linear-gradient(180deg, var(--red-grad-1), var(--red-grad-2));
  color: #FFF1F1;
  box-shadow: 0 0 20px rgba(255, 42, 42, 0.4);
}
.btn--panic:hover { box-shadow: 0 0 28px rgba(255, 42, 42, 0.55); }

.btn--small { padding: 11px 20px; font-size: 0.9375rem; }

.btn-row { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }

/* --------------------------------------------------------------------------
   8. Site header
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(10, 7, 20, 0.55);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid rgba(42, 33, 66, 0.6);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: var(--header-h);
}

/* The brand is the app's own badge plus the lettering: the regenerated ring
   mark next to heavy white ALLiN with the emerald baseline dot.

   ⚠️ USE assets/logo-mark.svg HERE, NOT assets/logo.svg. logo.svg is the full
   badge, drawn for 512px and up: at 38px its dotted orbit smears into grey
   mush and its glow only serves to dim the ring. logo-mark.svg is the same
   mark redrawn for small sizes, spending the orbit's radius on the rings and
   the lettering instead. Both come out of `npm run logo:build`.

   ⚠️ THE BADGE IS A COMPANION, NOT THE WHOLE MARK. Its inner wordmark is only
   ~9px of ink at this size and turns to mush on its own, so the lettering
   beside it is what actually carries the name. Dropping the lettering to "save
   space" makes the header unreadable. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  text-decoration: none;
}
.site-footer @media (max-width: 420px) {
  .brand { gap: 9px; }
  }

.site-nav {
  display: flex;
  align-items: center;
  gap: clamp(18px, 3vw, 34px);
}
.site-nav > a:not(.btn) {
  text-decoration: none;
  font-weight: 700;
  font-size: 0.9875rem;
  color: var(--text-2);
  transition: color 140ms ease;
}
.site-nav > a:not(.btn):hover { color: var(--text); }
.site-nav > a.is-active { color: var(--green); }

/* Hamburger, shown under 760px */
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 10px;
  background: transparent;
  border: 0;
  cursor: pointer;
}
.nav-toggle-bar {
  display: block;
  width: 24px;
  height: 2.5px;
  border-radius: 2px;
  background: var(--text);
  transition: transform 200ms ease, opacity 200ms ease;
}

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

  .site-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    padding: 12px var(--gutter) 20px;
    /* ⚠️ SOLID, NOT TRANSLUCENT. At 0.96 the hero headline still ghosted through
       the menu links (measured ~8/255 of bleed), and a dropdown has no reason to
       be see-through. Opaque also drops the backdrop-filter, which was doing
       real compositing work for an effect nothing could see. */
    background: var(--bg);
    border-bottom: 1px solid rgba(42, 33, 66, 0.6);
  }
  .site-nav > a:not(.btn) {
    padding: 12px 4px;
    font-size: 1.05rem;
    border-bottom: 1px solid rgba(42, 33, 66, 0.4);
  }
  .site-nav > .btn { margin-top: 12px; }

  .site-header.nav-open .site-nav { display: flex; }
  .site-header.nav-open .nav-toggle-bar:nth-child(1) { transform: translateY(7.5px) rotate(45deg); }
  .site-header.nav-open .nav-toggle-bar:nth-child(2) { opacity: 0; }
  .site-header.nav-open .nav-toggle-bar:nth-child(3) { transform: translateY(-7.5px) rotate(-45deg); }
}

/* --------------------------------------------------------------------------
   9. Phone frame (device bezel for app screenshots)
   -------------------------------------------------------------------------- */
.phone-frame {
  position: relative;
  width: min(300px, 82vw);
  padding: 10px;
  border-radius: 46px;
  background: var(--bg-deep);
  border: 1px solid var(--card-border);
  box-shadow:
    0 30px 70px rgba(0, 0, 0, 0.55),
    inset 0 0 0 2px rgba(234, 233, 242, 0.04);
}
/* No fake notch overlay: the captures have the app's own header right at the
   top, and covering it would hide real UI. The bezel alone reads as a phone. */
/* The screenshots are captured at 430x932 points; the screen keeps that exact
   ratio (set here, not on the frame) so nothing is cropped or squeezed. */
.phone-frame > img,
.phone-frame > .phone-screen {
  width: 100%;
  height: auto;
  aspect-ratio: 430 / 932;
  object-fit: cover;
  border-radius: 36px;
  background: var(--card);
  overflow: hidden;
}
.phone-frame--small { width: min(240px, 70vw); border-radius: 38px; }
.phone-frame--small > img, .phone-frame--small > .phone-screen { border-radius: 29px; }
.phone-frame--mini { width: min(198px, 58vw); padding: 8px; border-radius: 32px; }
.phone-frame--mini > img, .phone-frame--mini > .phone-screen { border-radius: 25px; }

/* --------------------------------------------------------------------------
   10. FAQ accordion (details/summary)
   -------------------------------------------------------------------------- */
.faq { display: grid; gap: 12px; max-width: 760px; }

.faq details {
  background: var(--card);
  border: 1px solid var(--card-border);
  border-radius: 20px;
  padding: 0 clamp(18px, 3vw, 24px);
}
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 18px 0;
  font-weight: 800;
  font-size: 1.05rem;
  color: var(--text);
  cursor: pointer;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  flex: none;
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1;
  color: var(--green);
  transition: transform 200ms ease;
}
.faq details[open] summary::after { transform: rotate(45deg); }
.faq .faq-body { padding: 0 0 20px; color: var(--text-2); }
.faq .faq-body a { color: var(--green); }

/* --------------------------------------------------------------------------
   11. Site footer
   -------------------------------------------------------------------------- */
.site-footer {
  background: var(--bg-deep);
  border-top: 1px solid rgba(42, 33, 66, 0.6);
  padding-block: clamp(48px, 6vw, 72px) 32px;
  font-size: 0.9375rem;
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr;
  gap: clamp(28px, 4vw, 48px);
}
@media (max-width: 860px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 480px) {
  .footer-grid { grid-template-columns: 1fr; }
}

.footer-brand .brand { margin-bottom: 14px; }
.footer-tagline { color: var(--text); font-weight: 800; }
.footer-tagline .hl { color: var(--green); }

.footer-col h3 {
  font-size: 0.8125rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 14px;
}
.footer-col a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 0;
  color: var(--text-2);
  text-decoration: none;
  transition: color 140ms ease;
}
.footer-col a:hover { color: var(--text); }
/* Social glyphs carry their real brand colors inline; keep them small and calm */
.footer-col a svg { width: 18px; height: 18px; flex: none; opacity: 0.92; transition: opacity 140ms ease; }
.footer-col a:hover svg { opacity: 1; }

.footer-helpline {
  margin-top: clamp(36px, 5vw, 52px);
  padding: 16px 20px;
  border: 1px solid var(--card-border);
  border-radius: 16px;
  background: var(--card);
  color: var(--text-2);
  font-size: 0.9375rem;
}
.footer-helpline a { color: var(--green); font-weight: 800; text-decoration: none; }
.footer-helpline a:hover { text-decoration: underline; }

.footer-legal-row {
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid rgba(42, 33, 66, 0.5);
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
  justify-content: space-between;
  color: var(--text-3);
  font-size: 0.875rem;
}

/* --------------------------------------------------------------------------
   12. Small helpers
   -------------------------------------------------------------------------- */
.center { text-align: center; }
.stack-sm > * + * { margin-top: 8px; }
.stack > * + * { margin-top: 16px; }
.mt-1 { margin-top: 8px; }
.mt-2 { margin-top: 16px; }
.mt-3 { margin-top: 24px; }
.mt-4 { margin-top: 40px; }

/* Wide content must scroll inside its own box, never the page */
.scroll-x { overflow-x: auto; }

/* Hero convenience */
.hero { padding-block: clamp(72px, 11vw, 140px) clamp(64px, 9vw, 112px); }
.hero .lead { margin-top: 20px; }
.hero .btn-row { margin-top: 32px; }

/* --------------------------------------------------------------------------
   13. Inner-page building blocks (about / features / support)
   -------------------------------------------------------------------------- */

/* Kicker tinted by the section's --accent (set an .accent-* class on the
   section wrapper).

   ⚠️ TEXT READS OFF --accent-text, NOT --accent. Two of the brand accents are
   dark enough that 13px bold on them lands under AA: cobalt (3.4:1) and the
   content-blocker red (4.5:1 borderline). Those are ICON colours in the app,
   never body text, so the two of them declare a lightened text tint and the
   chrome keeps the true brand colour. */
.kicker--accent { color: var(--accent-text, var(--accent)); }

/* Two-column feature split: copy on one side, media on the other.
   Put the media div first in the DOM to flip sides on desktop. */
.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}
.split-media {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  gap: clamp(16px, 2vw, 24px);
  position: relative;
}
/* Soft accent pool behind the media so screenshots sit in light instead of
   flat dark. Tinted by the section's --accent. */
.split-media::before,
.feature-media::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: min(460px, 92%);
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--accent) 26%, transparent), transparent 72%);
  filter: blur(30px);
  pointer-events: none;
}
.split-media > * { position: relative; }
.feature-media { position: relative; }
.feature-media > * { position: relative; }
@media (max-width: 860px) {
  .split { grid-template-columns: 1fr; }
  .split-media { order: 1; }
}
/* A pair of small frames sits side by side inside the split column */
.split-media .phone-frame--small { width: clamp(150px, 44%, 232px); }

/* Status pills reuse .soon-pill from the home page section.
   The 16-gem lineup reuses .gem-grid / .gem-tile from the home page section. */

/* Simple checked list, check mark tinted by --accent */
.checklist {
  list-style: none;
  padding: 0;
  display: grid;
  gap: 10px;
  color: var(--text-2);
}
.checklist li { position: relative; padding-left: 30px; }
.checklist li::before {
  content: "\2713";
  position: absolute;
  left: 0;
  top: 0;
  font-weight: 900;
  color: var(--accent);
}

/* Big calm helpline number on the support page */
.crisis-number {
  display: inline-block;
  font-size: clamp(1.5rem, 3.4vw, 2rem);
  font-weight: 900;
  letter-spacing: 0.01em;
  color: var(--text);
  text-decoration: none;
}
.crisis-number:hover { color: var(--accent); }

/* --------------------------------------------------------------------------
   13. Home page
   -------------------------------------------------------------------------- */

/* Hero: copy left, phone + floating gems right */
.hero--home { overflow-x: clip; padding-block: clamp(56px, 8vw, 110px) clamp(64px, 9vw, 112px); }

.hero-grid {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(36px, 5vw, 72px);
  align-items: center;
}
@media (max-width: 880px) {
  .hero-grid { grid-template-columns: 1fr; }
}

.hero-note { margin-top: 22px; font-size: 0.9375rem; color: var(--text-2); }
.hero-note strong { color: var(--text); }

/* Wordmark treatment inside a heading: ALLiN plus the signature green dot */
.wm { font-weight: 900; white-space: nowrap; }
.wm-dot {
  display: inline-block;
  width: 0.13em;
  height: 0.13em;
  margin-left: 0.06em;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 0.35em rgba(40, 230, 147, 0.8);
  vertical-align: baseline;
}

.hero-media {
  position: relative;
  width: min(300px, 76vw);
  margin-inline: auto;
}

.float-gem {
  position: absolute;
  z-index: 2;
  height: auto;
  filter: drop-shadow(0 0 18px var(--accent));
  animation: gem-float 7s ease-in-out infinite;
  pointer-events: none;
}
/* Anchored fully OUTSIDE the phone with a real gap (user: the gems must float
   around the phone, never touch it). right/left: 100% pins the gem's inner edge
   to the phone's edge; the extra px is the clearance. The float animation is
   translateY only, so drifting never carries a gem onto the frame. */
.float-gem--quartz { width: clamp(54px, 6vw, 72px); top: 2%; right: calc(100% + 18px); --accent: rgba(234, 242, 251, 0.55); }
.float-gem--emerald { width: clamp(62px, 7vw, 86px); top: 34%; left: calc(100% + 20px); --accent: rgba(69, 224, 140, 0.55); animation-delay: -2.4s; }
.float-gem--prism { width: clamp(70px, 8vw, 96px); bottom: 4%; right: calc(100% + 26px); --accent: rgba(255, 209, 102, 0.5); animation-delay: -4.6s; }

@media (max-width: 880px) {
  /* Stacked layout: the phone spans most of the viewport, so there is no side
     room to float beside it without touching it or spilling off-screen. */
  .float-gem { display: none; }
}

@keyframes gem-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-12px); }
}
@media (prefers-reduced-motion: reduce) {
  .float-gem { animation: none; }
}

/* Numbered loop cards ("how it helps"): an app-style icon disc (soft accent
   tint behind an accent glyph, like the app's Places / Lock it down discs)
   with the step number across from it. */
.step-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.step-icon {
  flex: none;
  width: 48px;
  height: 48px;
  border-radius: 15px;
  display: grid;
  place-items: center;
  background: color-mix(in srgb, var(--accent) 20%, rgba(10, 7, 20, 0.55));
  border: 1px solid color-mix(in srgb, var(--accent) 38%, transparent);
  color: var(--accent);
}
.step-icon svg { width: 24px; height: 24px; }
.step-num {
  display: inline-block;
  font-size: 0.8125rem;
  font-weight: 900;
  letter-spacing: 0.14em;
  /* Accent TEXT, so it takes the legible tint (see .kicker--accent) rather than
     the raw brand colour: 13px of #FF2A2A on the red card measured 4.29:1. */
  color: var(--accent-text, var(--accent));
}

/* Alternating feature bands */
.feature-band {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(28px, 5vw, 80px);
  align-items: center;
  padding-block: clamp(26px, 4vw, 44px);
}
.feature-band .kicker { color: var(--accent); }
.feature-band .phone-frame { margin-inline: auto; }
.feature-band--flip .feature-media { order: 2; }
.feature-copy h3 { font-size: clamp(1.5rem, 3vw, 2rem); }
.feature-copy p { margin-top: 12px; }
@media (max-width: 880px) {
  .feature-band { grid-template-columns: 1fr; }
  .feature-band .feature-media, .feature-band--flip .feature-media { order: 2; }
}

/* The 16-gem strip */
.gem-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: clamp(10px, 1.6vw, 16px);
}
@media (max-width: 1000px) { .gem-grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 480px) { .gem-grid { grid-template-columns: repeat(2, 1fr); } }

.gem-tile {
  text-align: center;
  padding: 16px 8px 14px;
  background: var(--card);
  border: 1px solid var(--card-border);
  border-radius: 18px;
  transition: border-color 220ms ease, background-color 220ms ease;
}
.gem-tile img {
  width: clamp(52px, 6vw, 68px);
  height: auto;
  margin: 0 auto 8px;
  transition: transform 260ms ease, filter 260ms ease;
}
@media (hover: hover) {
  .gem-tile:hover { border-color: rgba(234, 233, 242, 0.24); }
  .gem-tile:hover img { transform: translateY(-3px) scale(1.07); filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.5)); }
}
@media (prefers-reduced-motion: reduce) {
  .gem-tile:hover img { transform: none; }
}
.gem-tile .gem-name { display: block; font-weight: 800; font-size: 0.875rem; color: var(--text); }
.gem-tile .gem-day { display: block; font-size: 0.75rem; font-weight: 700; color: var(--text-3); }
.gem-tile--crown { border-color: color-mix(in srgb, var(--yellow) 45%, transparent); }
.gem-tile--crown .gem-day { color: var(--yellow); }

/* Community post cards. The avatar is the member's actual streak gem (the
   app's own render) in a round frame; the day count sits under the stage
   name as a small caption. Neutral frame so the gem carries the color. */
.post-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.gem-avatar {
  flex: none;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: radial-gradient(circle at 50% 38%, rgba(234, 233, 242, 0.07), transparent 72%), var(--elevated);
  border: 1px solid var(--card-border);
}
.gem-avatar img { width: 38px; height: 38px; }
.post-meta { font-weight: 800; color: var(--text); font-size: 0.9375rem; }
.post-meta small { display: block; font-weight: 700; color: var(--text-3); font-size: 0.78rem; }

/* No member-quote styles live here on purpose. The testimonial section was cut
 * from the site in the 2026-08-09 copy pass: every quote on it was written by
 * us, and inventing members who say the app worked is the one claim this site
 * must never make. The rules that styled it are deleted rather than left
 * dormant, so nothing is sitting here ready to be switched back on.
 * .gem-avatar above survives because the Connect chat mock still uses it. */

/* Blocker band: real screenshots in mini phone frames inside the cards */
.blocker-card { text-align: left; }
.blocker-card .phone-frame { margin: 6px auto 20px; }

/* Extension notify form (not live, does not submit anywhere) */
.notify-form { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; }
.notify-form input {
  flex: 1;
  min-width: 180px;
  padding: 13px 18px;
  border-radius: 999px;
  border: 1px solid var(--chip-border);
  background: var(--chip);
  color: var(--text);
  font-family: inherit;
  font-size: 0.9375rem;
}
.notify-form input::placeholder { color: var(--text-3); }
.notify-form input:focus { outline: 2px solid color-mix(in srgb, var(--green) 60%, transparent); outline-offset: 1px; }
.notify-note { margin-top: 10px; font-size: 0.8125rem; color: var(--text-3); }

.soon-pill {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--teal) 50%, transparent);
  color: var(--teal);
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-bottom: 12px;
}

/* Store badge placeholders (no live store links yet) */
.store-badges { display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; margin-top: 32px; }
.store-badge {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 12px 26px;
  border-radius: 16px;
  border: 1px solid var(--chip-border);
  background: var(--chip);
  text-align: left;
  line-height: 1.2;
}
.store-badge small { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-3); }
.store-badge strong { font-size: 1.05rem; font-weight: 800; color: var(--text); }

/* Centered helpers for home sections */
.faq--center { margin-inline: auto; }
.section-foot { margin-top: clamp(24px, 4vw, 40px); }

/* --------------------------------------------------------------------------
   13. Legal pages (terms, privacy, subscription terms)
   Single readable column of section cards with a sticky table of contents
   on desktop. Bracketed placeholders get a visible fill-in treatment.
   -------------------------------------------------------------------------- */
.legal-hero { padding-block: clamp(56px, 8vw, 96px) clamp(24px, 4vw, 40px); }
.legal-hero h1 { font-size: clamp(2.1rem, 5vw, 3.2rem); }
/* ⚠️ SECONDARY, NOT MUTED. The legal hero is the one place on the site where
   body text sits on the BRIGHTEST part of the aurora, and --text-3 measured
   3.99:1 there at 1440 and 4.14:1 at 390, i.e. under AA on every legal page.
   --text-2 on the same pixels measures 5.9:1. */
.legal-meta { margin-top: 12px; color: var(--text-2); font-size: 0.9375rem; }

/* Switcher pills linking the three legal documents to each other */
.legal-switch { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 26px; }
/* ⚠️ THESE PILLS SIT ON THE HOTTEST PIXELS ON THE SITE. A translucent fill and
   --text-2 measured 3.57:1 at 390 and 4.09:1 at 1440 on the pill that lands
   furthest right, where the aurora is brightest, and the pill itself visibly
   dissolved into the purple. An opaque chip plus --text is 12.6:1 and, more to
   the point, looks like the same control on all four documents. */
.legal-switch a {
  display: inline-flex;
  align-items: center;
  padding: 9px 18px;
  border-radius: 999px;
  border: 1px solid var(--chip-border);
  background: var(--chip);
  color: var(--text);
  font-size: 0.9rem;
  font-weight: 700;
  text-decoration: none;
  transition: color 140ms ease, background-color 140ms ease, border-color 140ms ease;
}
.legal-switch a:hover { border-color: var(--text-2); background: var(--chip-hover); }
.legal-switch a.is-current {
  color: var(--green);
  border-color: color-mix(in srgb, var(--green) 60%, transparent);
  background: var(--chip);
}

/* Two-column layout: sticky TOC + document body. Stacks under 940px. */
.legal-layout {
  display: grid;
  grid-template-columns: 252px minmax(0, 1fr);
  gap: clamp(24px, 4vw, 48px);
  align-items: start;
  padding-bottom: clamp(64px, 9vw, 112px);
}
/* ⚠️ THE STICKY TOC HAS TO SCROLL ITSELF. Terms lists 32 sections, which is
   1314px of pins against 804px of room on a 1440x900 desktop, so roughly the
   last twelve links sat below the fold of a box that never moves and could
   never be reached. Privacy overflowed too. Capping it to the free height and
   letting it scroll is the only thing that reaches them; `overscroll-behavior`
   keeps a flick inside the list from running on down the document. */
.legal-toc {
  position: sticky;
  top: calc(var(--header-h) + 24px);
  max-height: calc(100vh - var(--header-h) - 48px);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--chip-border) transparent;
  padding: 20px 22px;
  border-radius: 20px;
}
.legal-toc::-webkit-scrollbar { width: 8px; }
.legal-toc::-webkit-scrollbar-track { background: transparent; }
.legal-toc::-webkit-scrollbar-thumb {
  background: var(--chip-border);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: content-box;
}
.legal-toc h2 {
  font-size: 0.8125rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 12px;
}
.legal-toc ol {
  margin: 0;
  padding-left: 20px;
  display: grid;
  gap: 2px;
  color: var(--text-3);
  font-size: 0.9rem;
}
.legal-toc a {
  display: block;
  padding: 3px 0;
  color: var(--text-2);
  font-weight: 600;
  text-decoration: none;
  transition: color 140ms ease;
}
.legal-toc a:hover { color: var(--green); }
/* It inherits .card, but now that it is a scroll container you hover it to READ
   it, and a card that lifts 3px under the pointer makes the list jitter while
   you are scrolling it. */
.legal-toc:hover { transform: none; box-shadow: none; border-color: var(--card-border); }

@media (max-width: 940px) {
  .legal-layout { grid-template-columns: 1fr; }
  /* Stacked above the document it is not sticky, so it must not be a nested
     scroller either: the page itself is the scroll container down here. */
  .legal-toc { position: static; max-height: none; overflow: visible; }
}

/* Document body: one card per major section */
.legal-body { display: grid; gap: clamp(14px, 2vw, 20px); min-width: 0; }
.legal-section { scroll-margin-top: calc(var(--header-h) + 20px); }
.legal-section h2 { font-size: clamp(1.2rem, 2vw, 1.4rem); font-weight: 800; }
.legal-section h3 { font-size: 1.05rem; margin-top: 18px; }
.legal-section p, .legal-section li { color: var(--text-2); }
.legal-section h2 + p, .legal-section p + p, .legal-section p + ul, .legal-section ul + p { margin-top: 12px; }
.legal-section h3 + p, .legal-section h3 + ul { margin-top: 8px; }
.legal-section ul { margin: 0; padding-left: 22px; display: grid; gap: 8px; }
.legal-section li::marker { color: var(--text-3); }
.legal-section a { color: var(--green); font-weight: 700; text-decoration: none; }
.legal-section a:hover { text-decoration: underline; }
.legal-section strong { color: var(--text); }

/* Bracketed placeholder the owner must replace before launch */
.fill-in {
  display: inline-block;
  padding: 0 7px;
  border-radius: 7px;
  border: 1px dashed color-mix(in srgb, var(--yellow) 55%, transparent);
  background: color-mix(in srgb, var(--yellow) 12%, transparent);
  color: var(--yellow);
  font-weight: 700;
  font-style: normal;
}

/* Quiet note card, for the counsel-review reminder at the end of a document */
.legal-note {
  border-radius: 20px;
  padding: 16px 20px;
  color: var(--text-3);
  font-size: 0.9375rem;
}

/* --------------------------------------------------------------------------
   14. About page
   -------------------------------------------------------------------------- */

/* Emerald wordmark treatment for ALLiN mentions in running copy */
.allin { color: var(--green); }
p .allin,
li .allin { font-weight: 800; }

/* Living gem, animated like the app's dashboard stone: slow float, a pulsing
   layered glow behind it, a periodic glint sweeping across the stone itself,
   and quiet sparkles. The glint is a gradient sliver masked by the gem PNG
   (set --gem-img inline on .gem-hero) so light only crosses the stone.

   ⚠️ --gem-img MUST BE SET WITH A ROOT-RELATIVE URL ("/assets/..."). A url()
   carried in a custom property is resolved against the stylesheet where the
   var() is USED, which is this file, not the page that declared it. A
   document-relative "assets/..." therefore resolves to /css/assets/... , 404s,
   and the glint loses its mask and stops being clipped to the stone. */
.gem-hero {
  position: relative;
  width: min(380px, 78vw);
}
.gem-hero::before {
  content: "";
  position: absolute;
  inset: 2%;
  border-radius: 50%;
  background:
    radial-gradient(closest-side, rgba(255, 255, 255, 0.20), transparent 46%),
    radial-gradient(closest-side, rgba(169, 107, 255, 0.46), transparent 66%),
    radial-gradient(closest-side, rgba(63, 192, 245, 0.22), transparent 82%);
  filter: blur(16px);
  animation: gem-glow-breathe 6.5s ease-in-out infinite;
}
.gem-hero > img {
  position: relative;
  z-index: 1;
  width: 100%;
  height: auto;
  animation: gem-hero-float 7.5s ease-in-out infinite;
}
.gem-hero .gem-glint {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  -webkit-mask-image: var(--gem-img);
  -webkit-mask-size: contain;
  -webkit-mask-position: center;
  -webkit-mask-repeat: no-repeat;
  mask-image: var(--gem-img);
  mask-size: contain;
  mask-position: center;
  mask-repeat: no-repeat;
  background: linear-gradient(115deg,
    transparent 40%,
    rgba(255, 255, 255, 0.05) 46%,
    rgba(255, 255, 255, 0.6) 50%,
    rgba(255, 255, 255, 0.05) 54%,
    transparent 60%);
  background-size: 320% 100%;
  background-repeat: no-repeat;
  background-position: 140% 0;
  /* Rides the same float as the stone so the sliver stays locked to it */
  animation: gem-hero-float 7.5s ease-in-out infinite, gem-glint-sweep 7.5s linear infinite;
}
@keyframes gem-glint-sweep {
  0%, 55% { background-position: 140% 0; }
  70%, 100% { background-position: -40% 0; }
}
.gem-sparkle {
  position: absolute;
  z-index: 2;
  width: 14px;
  height: 14px;
  pointer-events: none;
  opacity: 0;
  animation: gem-sparkle-twinkle 5.6s ease-in-out infinite;
}
.gem-sparkle::before,
.gem-sparkle::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  border-radius: 2px;
  background: #FFFFFF;
  box-shadow: 0 0 8px rgba(255, 255, 255, 0.85);
  transform: translate(-50%, -50%);
}
.gem-sparkle::before { width: 2px; height: 100%; }
.gem-sparkle::after { width: 100%; height: 2px; }
.gem-sparkle--1 { top: 14%; right: 16%; }
.gem-sparkle--2 { bottom: 22%; left: 12%; width: 10px; height: 10px; animation-delay: -2.6s; }
.gem-sparkle--3 { top: 42%; left: 5%; width: 8px; height: 8px; animation-delay: -4.1s; }

@keyframes gem-hero-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-14px); }
}
@keyframes gem-glow-breathe {
  0%, 100% { opacity: 0.55; transform: scale(0.96); }
  50% { opacity: 1; transform: scale(1.05); }
}
@keyframes gem-sparkle-twinkle {
  0%, 26%, 100% { opacity: 0; transform: scale(0.35); }
  8% { opacity: 1; transform: scale(1); }
  16% { opacity: 0; transform: scale(0.35); }
}

/* Reduced motion: everything rests still, glow and sparkles stay visible,
   the glint never sweeps */
@media (prefers-reduced-motion: reduce) {
  .gem-hero > img,
  .gem-hero::before { animation: none; }
  .gem-hero .gem-glint { animation: none; background: none; }
  .gem-sparkle { animation: none; opacity: 0.8; transform: scale(0.9); }
  .orbit-gem { animation: none; }
}

/* Composed panel (about page): a phone frame with small gems anchored to its
   edges. The wrapper is exactly the phone's size so offsets track the phone. */
.collage { position: relative; width: fit-content; margin-inline: auto; }
@media (max-width: 560px) {
  /* No side room on small screens; the gems would clip at the viewport edge */
  .collage .orbit-gem { display: none; }
}

/* Small gems orbiting a composed panel (about page). Positions are set per
   gem inline; the float is translateY only so a gem never drifts onto the
   phone. */
.orbit-gem {
  position: absolute;
  z-index: 2;
  width: clamp(56px, 7vw, 84px);
  height: auto;
  pointer-events: none;
  filter: drop-shadow(0 0 16px var(--accent, rgba(169, 107, 255, 0.5)));
  animation: gem-float 7s ease-in-out infinite;
}

/* Milestone stones inline with running copy: gem, name, day caption */
.stone-row {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(14px, 3vw, 28px);
  margin-top: 22px;
}
.stone-row .stone {
  display: grid;
  justify-items: center;
  gap: 2px;
  text-align: center;
}
.stone-row .stone img { width: clamp(48px, 6vw, 64px); height: auto; margin-bottom: 4px; }
.stone-row .stone strong { font-size: 0.875rem; color: var(--text); }
.stone-row .stone small { font-size: 0.75rem; font-weight: 700; color: var(--text-3); }

/* Value cards: soft tinted icon disc in the card's accent, like the app.
   The accent comes from the card's .accent-* helper (root default is green). */
.value-icon {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  margin-bottom: 14px;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 38%, transparent);
  box-shadow: 0 0 18px color-mix(in srgb, var(--accent) 16%, transparent);
}
.value-icon svg { width: 26px; height: 26px; }

/* --------------------------------------------------------------------------
   14. Features page: immersive tour
   -------------------------------------------------------------------------- */

/* Designed assessment screen inside a phone frame. A stylized representation
   of the in-app onboarding quiz built from the app's real UI language (the
   violet gradient, emerald progress and selection, pill options with icon
   discs); it is not a screenshot and the page marks it as designed. */
/* Selector carries the frame for specificity: the frame's generic
   .phone-screen background would win over a lone class otherwise */
.phone-frame > .mock-quiz {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 54px 18px 22px;
  background: linear-gradient(180deg, #4B38AC 0%, #2E2180 46%, #120E33 100%);
}
.mock-progress {
  flex: none;
  height: 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.18);
  overflow: hidden;
}
.mock-progress span {
  display: block;
  width: 25%;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--cta-grad-1), var(--green-deep));
}
.mock-step {
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--green);
}
.mock-q {
  font-size: clamp(1.1rem, 1.9vw, 1.35rem);
  line-height: 1.2;
  color: #FFFFFF;
}
.mock-options {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  display: grid;
  gap: 10px;
}
.mock-options li {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 14px;
  border-radius: 18px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.08);
  font-weight: 700;
  font-size: 0.92rem;
  color: rgba(255, 255, 255, 0.86);
}
.mock-opt-icon {
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 10px;
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.9);
}
.mock-opt-icon svg { width: 16px; height: 16px; }
.mock-options li.is-picked {
  border-color: color-mix(in srgb, var(--green) 80%, transparent);
  background: color-mix(in srgb, var(--green) 20%, rgba(255, 255, 255, 0.04));
  color: #FFFFFF;
  box-shadow: 0 0 16px color-mix(in srgb, var(--green) 22%, transparent);
}
.mock-options li.is-picked .mock-opt-icon {
  background: color-mix(in srgb, var(--green) 30%, transparent);
  color: var(--green);
}
.mock-check {
  margin-left: auto;
  flex: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--green);
  color: #06231A;
}
.mock-check svg { width: 12px; height: 12px; }
.mock-cta {
  margin-top: auto;
  text-align: center;
  padding: 13px;
  border-radius: 999px;
  background: linear-gradient(180deg, var(--cta-grad-1), var(--cta-grad-2));
  color: var(--cta-text);
  font-weight: 800;
  font-size: 0.95rem;
  box-shadow: 0 0 18px rgba(40, 230, 147, 0.35);
}

/* Illustrative community post cluster: anonymous cards attributed only by
   day count and gem stage, never by name. Marked illustrative on the page. */
.post-cluster { display: grid; gap: 16px; width: min(430px, 100%); }
.post-cluster .post-card:nth-child(2) { transform: translateX(clamp(0px, 3vw, 28px)); }
.post-cluster .post-card:nth-child(3) { transform: translateX(clamp(-28px, -3vw, 0px)); }
.post-card .post-body {
  margin-top: 2px;
  color: var(--text);
  font-size: 0.96rem;
  line-height: 1.5;
}
/* The avatar itself is the shared .gem-avatar defined with the community
   post cards above; the cluster reuses it unchanged. */
.cluster-note { margin-top: 4px; font-size: 0.8125rem; color: var(--text-3); }

/* --------------------------------------------------------------------------
   15. Connect chat mock (home page)
   A designed representation of the app's ALL IN Chat room: dark rounded
   card, colored-initial avatars, left-aligned bubbles. Not a screenshot.
   -------------------------------------------------------------------------- */
.chat-card {
  width: min(560px, 100%);
  margin-inline: auto;
  border-radius: var(--radius-card);
  border: 1px solid var(--card-border);
  background: linear-gradient(180deg, #171126 0%, #0D0917 100%);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
  overflow: hidden;
}
.chat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 20px;
  border-bottom: 1px solid rgba(42, 33, 66, 0.8);
  background: rgba(234, 233, 242, 0.03);
}
.chat-title { font-weight: 900; font-size: 1.05rem; color: var(--text); }
.chat-title small {
  display: block;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--text-3);
}
.chat-pill {
  flex: none;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--green) 45%, transparent);
  color: var(--green);
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.chat-list {
  display: grid;
  gap: 14px;
  padding: 20px;
}
.chat-msg { display: flex; align-items: flex-start; gap: 11px; }
.chat-avatar {
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-weight: 900;
  font-size: 0.95rem;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 18%, rgba(10, 7, 20, 0.6));
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
}
.chat-body { min-width: 0; }
.chat-meta {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 4px;
}
.chat-meta strong { font-size: 0.85rem; font-weight: 800; color: var(--text); }
.chat-meta small { font-size: 0.72rem; font-weight: 700; color: var(--text-3); }
.chat-day {
  font-size: 0.72rem;
  font-weight: 800;
  color: var(--green);
}
.chat-bubble {
  display: inline-block;
  padding: 9px 13px;
  border-radius: 4px 16px 16px 16px;
  background: rgba(234, 233, 242, 0.07);
  border: 1px solid rgba(234, 233, 242, 0.06);
  color: var(--text);
  font-size: 0.95rem;
  line-height: 1.45;
}
.chat-foot {
  padding: 12px 20px 16px;
  border-top: 1px solid rgba(42, 33, 66, 0.8);
  color: var(--text-3);
  font-size: 0.8125rem;
}

/* --------------------------------------------------------------------------
   16. Support page: calm band and icon panels
   -------------------------------------------------------------------------- */
.calm-band {
  position: relative;
  overflow: hidden;
  border-radius: 30px;
  border: 1px solid var(--card-border);
  background:
    radial-gradient(60% 80% at 12% 0%, rgba(63, 192, 245, 0.22), transparent 70%),
    radial-gradient(50% 70% at 90% 20%, rgba(47, 216, 194, 0.18), transparent 70%),
    radial-gradient(55% 80% at 60% 100%, rgba(169, 107, 255, 0.2), transparent 72%),
    linear-gradient(180deg, #191231 0%, #0C0917 100%);
  padding: clamp(24px, 4vw, 44px);
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  gap: clamp(24px, 4vw, 48px);
  align-items: center;
}
@media (max-width: 760px) {
  .calm-band { grid-template-columns: 1fr; }
}
.calm-band .phone-frame { margin-inline: auto; }


/* ------------------------------------------------------------------ *
 * About hero: the "odds wall".
 * The page opened on a bare headline over flat background and read dead.
 * This is the thing the copy is arguing with, a wall of betting-app noise
 * fading out behind the one stone that means the opposite. Decorative only,
 * so it is aria-hidden and never carries meaning.
 * ------------------------------------------------------------------ */
.hero-media--about {
  position: relative; min-height: 460px; display: grid; place-items: center;
}

/* The full sixteen-stone journey as a ring: Quartz at day 0 sits at twelve
   o'clock and it runs clockwise to Prism at day 365, so the circle closes on a
   year. Order and thresholds mirror src/lib/gems.ts, and it should stay that
   way, because a shuffled ring stops meaning anything.
   ⚠️ Replaced an "odds wall" of betting chips (2026-08-10, user: "it looks
   terrible"). Do not bring that back. */
.gem-ring {
  position: relative; width: 100%; max-width: 460px; aspect-ratio: 1;
  display: grid; place-items: center;
  /* Ring radius and stone size, both fluid so the circle survives a phone. */
  --r: clamp(106px, 22vw, 182px);
  --gem: clamp(46px, 9.6vw, 80px);
}
/* A soft core, so the middle reads as light being gathered rather than a hole. */
.gem-ring-core {
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(circle at 50% 50%, rgba(47, 217, 140, 0.26) 0%, rgba(47, 217, 140, 0) 42%),
    radial-gradient(circle at 50% 50%, rgba(132, 122, 232, 0.32) 0%, rgba(132, 122, 232, 0) 60%);
}
.gem-ring-orbit { position: absolute; inset: 0; }
/* Placement trick: rotate to the stone's angle, push it out by the radius, then
   un-rotate by the same angle so the stone itself stays upright.
   ⚠️ grid + place-items:center is load bearing. The sixteen stones have
   different aspect ratios, so top-aligning them inside a square slot pushed the
   taller ones outward and the circle came out visibly lumpy. */
.gem-ring-item {
  position: absolute; top: 50%; left: 50%;
  width: var(--gem); height: var(--gem); margin: calc(var(--gem) / -2);
  display: grid; place-items: center;
  transform: rotate(var(--a)) translateY(calc(var(--r) * -1)) rotate(calc(var(--a) * -1));
}
.gem-ring-item img {
  max-width: 100%; max-height: 100%; width: auto; height: auto; display: block;
  filter: drop-shadow(0 6px 18px rgba(0, 0, 0, 0.45)) drop-shadow(0 0 22px rgba(169, 107, 255, 0.22));
}
@media (max-width: 860px) { .hero-media--about { min-height: 340px; margin-top: 26px; } }

/* The ring turns very slowly, and each stone counter-turns at exactly the same
   rate so none of them ends up upside down. 150s is deliberate: it should read
   as alive rather than as an animation you notice. */
@media (prefers-reduced-motion: no-preference) {
  .gem-ring-orbit { animation: gem-ring-spin 150s linear infinite; }
  .gem-ring-item img { animation: gem-ring-counter 150s linear infinite; }
  @keyframes gem-ring-spin { to { transform: rotate(360deg); } }
  @keyframes gem-ring-counter { to { transform: rotate(-360deg); } }
}


/* Two phones in one media slot: the Reality list and the Fallacies list, which
   are two halves of the same feature.
   ⚠️ Flex with EXPLICIT widths, not percentages and not absolute positioning.
   The first attempt used position:absolute + z-index:-1 and painted the second
   phone over the section below; the second used percentage widths, which resolve
   against the wide media column and made the back phone larger than the front
   one and pushed it over the copy. */
.phone-pair { display: flex; align-items: center; justify-content: center; }
.phone-pair .phone-frame { flex: 0 0 auto; }
/* ⚠️ SIZE THE PAIR OFF THE CONTAINER, NOT THE VIEWPORT. Both frames used to be
   vw-based (54vw + 70vw less a 46px overlap), which ignores the page gutters:
   at 360px that summed to 344px inside a 320px column and the front phone plus
   the copy beside it were silently clipped by body{overflow-x:hidden}. As
   percentages the pair is 100% - the overlap by construction, at any width. */
.phone-pair { max-width: 100%; }
.phone-pair .phone-frame--behind {
  order: -1;
  width: min(186px, 42%);
  margin-right: -58px;
  transform: rotate(-7deg) translateY(4%);
  opacity: 0.88;
}
.phone-pair .phone-frame:not(.phone-frame--behind) {
  position: relative;
  z-index: 1;
  width: min(240px, 58%);
}
@media (max-width: 700px) {
  .phone-pair .phone-frame--behind { margin-right: -46px; }
}
