/* SubShadow — subshadow.app
   Single shared stylesheet. Dark, cinematic; tokens mirror the app's
   launch background (#212D50) and New York/SF typography. No JS on the site. */

:root {
  --bg: #16203a;
  --surface: #212d50;
  --surface-raised: #2a3862;
  --ink: #eef1f7;
  --muted: #a9b4cf;
  --accent: #6ea8ff;
  --accent-strong: #8dbcff;
  --line: rgba(238, 241, 247, 0.12);
  --font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-serif: "New York", ui-serif, Georgia, serif;
  --font-jp: "Hiragino Mincho ProN", "Yu Mincho", "Noto Serif JP", serif;
  --radius-card: 16px;
  --radius-control: 12px;
  --radius-chip: 999px;
}

* { box-sizing: border-box; }

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

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 17px;
  line-height: 1.6;
}

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

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-strong); text-decoration: underline; }

/* A link inside running text is underlined at rest: against the muted body text
   the accent is only 1.16:1, so colour alone doesn't mark it (WCAG 1.4.1). Nav,
   footer and CTA links aren't in a <p>/<li> and stay bare. */
main p a:not(.link-arrow), main li a {
  text-decoration: underline;
  text-decoration-color: rgba(110, 168, 255, 0.55);
  text-underline-offset: 0.18em;
}
main p a:not(.link-arrow):hover, main li a:hover { text-decoration-color: currentColor; }

[lang="ja"] { font-family: var(--font-jp); }

h1, h2, h3 {
  font-family: var(--font-serif);
  font-weight: 600;
  line-height: 1.2;
  margin: 0 0 0.5em;
  letter-spacing: 0.01em;
}

h1 { font-size: clamp(2.1rem, 5vw, 3.1rem); }
h2 { font-size: clamp(1.6rem, 3.5vw, 2.1rem); }
h3 { font-size: 1.15rem; }

.container {
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 24px;
}

section { padding: 72px 0; }

.section-lead {
  color: var(--muted);
  max-width: 46rem;
  margin: 0 0 2.5rem;
}

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

.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: rgba(22, 32, 58, 0.85);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}

.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 60px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-serif);
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--ink);
}
.brand:hover { color: var(--ink); text-decoration: none; }

.brand img {
  width: 30px;
  height: 30px;
  border-radius: 7px;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 22px;
  font-size: 0.95rem;
}

.site-nav a { color: var(--muted); }
.site-nav a:hover { color: var(--ink); text-decoration: none; }

/* On a phone the nav drops to its own row under the brand rather than hiding:
   Pricing and the FAQ are 8+ screens down there, and the visitor's first
   questions are what it costs and whether it needs a server. "Features" is the
   one link left out — it's the section straight under the hero. */
@media (max-width: 640px) {
  .site-header .container {
    flex-wrap: wrap;
    row-gap: 0;
    min-height: 52px;
  }
  .brand { min-height: 52px; }
  .site-nav {
    flex-basis: 100%;
    justify-content: space-between;
    gap: 12px;
    padding-bottom: 10px;
    font-size: 0.9rem;
  }
  .site-nav a:first-child { display: none; }
  /* The taller header would cover a section's heading after an anchor jump. */
  section[id] { scroll-margin-top: 24px; }
}

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

.hero {
  padding: 88px 0 96px;
  background:
    radial-gradient(1000px 500px at 75% -10%, rgba(110, 168, 255, 0.14), transparent 65%),
    linear-gradient(180deg, var(--surface) 0%, var(--bg) 78%);
  border-bottom: 1px solid var(--line);
}

/* minmax(0, …) on every track that holds a phone bezel. A bare `1fr` takes its
   automatic minimum from the item's min-content, and the bezel's is a hard
   300px (its `max-width: 100%` is a cyclic percentage the browser discards
   during that pass) — so the track floors at 300px and the page scrolls
   sideways on a 320pt screen instead of the phone shrinking. */
.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  gap: 56px;
  align-items: center;
}

@media (max-width: 820px) {
  .hero-grid { grid-template-columns: minmax(0, 1fr); }
  /* max-width as well as the centring: justify-self shrink-wraps this to the
     bezel's 300px, which on a 320pt screen spills out of the page gutter. */
  .hero-visual { justify-self: center; max-width: 100%; }
}

.hero-copy .sub {
  color: var(--muted);
  font-size: 1.12rem;
  max-width: 34rem;
  margin: 1rem 0 2rem;
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px;
}

/* Pre-release status, deliberately not button-shaped: there's nothing to tap
   until the app is out. Release day swaps it for the .badge-store link. */
.badge-soon {
  display: inline-flex;
  flex-direction: column;
  color: var(--ink);
  line-height: 1.25;
}
.badge-soon small { font-size: 0.8rem; color: var(--muted); }
.badge-soon strong { font-size: 1.05rem; font-weight: 600; }

.link-arrow { font-size: 1rem; }

.fineprint {
  color: var(--muted);
  font-size: 0.85rem;
  margin-top: 1.4rem;
}

/* ---------- Phone mockup ---------- */

.phone {
  /* max-width so the bezel — a fixed-width box — shrinks instead of forcing a
     horizontal scroll on a 320pt phone. Never size this against an `auto` grid
     track: a percentage here is cyclic, and the track resolved it once as "take
     everything" (626px around a 300px phone) and once as zero (a 26px sliver of
     pure bezel). The step rows give the phone an explicit 300px column for that
     reason.

     The height comes from .phone-screen's aspect-ratio plus this padding and
     border — deliberately NOT from an `aspect-ratio` here. That is what the
     bezel used to do (9/19), and it sized the *border* box, so the screen
     inside it — inset 13px a side — came out at 0.4512 against a 0.4601
     capture. `object-fit: cover` then shaved 2.7px off each edge of every
     screenshot, cutting away the captured phone's own screen margin so the app
     content ran flush into the frame and looked like it was spilling out. */
  width: 300px;
  max-width: 100%;
  border-radius: 44px;
  border: 3px solid #3a4770;
  background: #05070d;
  box-shadow:
    0 24px 60px rgba(0, 0, 0, 0.5),
    0 0 0 1px rgba(238, 241, 247, 0.06);
  padding: 10px;
  position: relative;
}

.phone::before {
  /* Dynamic Island */
  content: "";
  position: absolute;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  width: 84px;
  height: 24px;
  border-radius: 999px;
  background: #000;
  z-index: 2;
}

/* The screen carries the aspect ratio, and it is the SHOT's ratio, not the
   phone's: the four captures are 1206x2622 (iPhone 17 @3x), resampled to
   900x1956 (the ratio of the 600 / 1304 below). Matching it here makes
   `object-fit: cover` below an exact fit that crops nothing, so each
   screenshot keeps its own screen margin and rounded corners and reads as a
   screen inside a bezel rather than as artwork bleeding past one. Re-check
   this if the capture device ever changes. */
.phone-screen {
  width: 100%;
  aspect-ratio: 600 / 1304;
  border-radius: 34px;
  overflow: hidden;
  position: relative;
  background: #05070d;
}

/* `cover` rather than `fill` so a shot whose ratio drifts slightly still fills
   the frame instead of stretching; with the ratio matched above it is a no-op. */
.phone-screen img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
}

/* The hero's demo loop, laid exactly over the still: it is encoded at the still's
   900x1956, so the swap moves nothing. Invisible until it is actually playing, so a
   video that never starts never hides the still. */
.phone-screen .hero-loop {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  opacity: 0;
  transition: opacity 0.4s ease;
}
.phone-screen .hero-loop.is-playing { opacity: 1; }

/* Under the bezel, centred on it whichever way the hero grid places the phone.
   Absolute, so the hero is the same height with or without it. */
.loop-toggle {
  position: absolute;
  top: calc(100% + 16px);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 14px;
  font: inherit;
  font-size: 0.85rem;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--radius-chip);
  cursor: pointer;
}
.loop-toggle:hover { color: var(--ink); border-color: rgba(238, 241, 247, 0.3); }
.loop-toggle[hidden] { display: none; }
.loop-toggle svg { width: 11px; height: 11px; fill: currentColor; }
.loop-toggle .icon-play,
.loop-toggle.is-paused .icon-pause { display: none; }
.loop-toggle.is-paused .icon-play { display: block; }

/* The three How-it-works shots. At the 208px this used to be, a full iPhone screen
   downscales ~2.4x and the transcript text stops being readable — which defeats
   the point of showing the real app. Everything but the shadow carries over from
   .phone, so the bezel, padding and Dynamic Island stay in proportion. */
.phone--sm {
  box-shadow: 0 14px 32px rgba(0, 0, 0, 0.45);
}


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

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

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 24px;
}

.card h3 { margin-bottom: 0.4em; }
.card p { margin: 0; color: var(--muted); font-size: 0.98rem; }

/* ---------- How it works ---------- */

.steps {
  list-style: none;
  counter-reset: step;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 20px;
}

/* One full-width row per step — copy left, phone right. Three columns cannot
   hold a phone wide enough to read the screen inside it, so the section trades
   height for a screenshot that actually shows something. */
.steps li {
  counter-increment: step;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 32px;
  display: grid;
  /* An explicit 300px for the phone, not `auto` — see the note on .phone.
     minmax(0, 1fr) rather than 1fr so a long unbroken string in the copy can
     never push the column past its share. */
  grid-template-columns: minmax(0, 1fr) 300px;
  column-gap: clamp(24px, 5vw, 56px);
  align-items: center;
}

/* Below the width where copy and a 300px phone both sit comfortably side by
   side, stack them. 880px rather than a tighter breakpoint because at 768px the
   copy column is squeezed to ~315px, which reads worse than the stack does. */
@media (max-width: 880px) {
  .steps li { grid-template-columns: minmax(0, 1fr); }
  .steps li .phone--sm { margin: 28px auto 0; }
}

/* The counter hangs off .step-copy, not the li: on the li it would be a grid
   item of its own and get stranded mid-row by align-items, far above the
   heading it numbers. */
.step-copy::before {
  content: counter(step);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--accent);
  color: #0b1226;
  font-weight: 700;
  margin-bottom: 14px;
}

.steps p { color: var(--muted); font-size: 0.98rem; margin-bottom: 0; }

.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }

.chip {
  border: 1px solid var(--line);
  border-radius: var(--radius-chip);
  padding: 3px 12px;
  font-size: 0.85rem;
  color: var(--muted);
}

/* ---------- Pricing ---------- */

.compare {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 3rem;
  font-size: 0.98rem;
}

.compare th, .compare td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
  text-align: left;
}

.compare th:not(:first-child), .compare td:not(:first-child) {
  text-align: center;
  width: 130px;
}

.compare thead th {
  font-family: var(--font-serif);
  font-size: 1.05rem;
  border-bottom-width: 2px;
}

.compare td { color: var(--muted); }
.compare td.yes { color: var(--accent-strong); }

/* A fixed 130px per value column leaves the feature labels ~119px on a phone,
   wrapping them to 3–5 lines. There the value columns shrink to their content. */
@media (max-width: 560px) {
  .compare th, .compare td { padding: 12px 8px; }
  .compare th:not(:first-child), .compare td:not(:first-child) {
    width: 1%;
    white-space: nowrap;
  }
}

.plans {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 20px;
  align-items: stretch;
}

.plan {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 26px 24px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  position: relative;
}

.plan.featured { border-color: var(--accent); }

.plan .flag {
  position: absolute;
  top: -12px;
  left: 22px;
  background: var(--accent);
  color: #0b1226;
  font-size: 0.75rem;
  font-weight: 700;
  border-radius: var(--radius-chip);
  padding: 2px 12px;
}

.plan h3 { margin-bottom: 0; }

.plan .price {
  font-family: var(--font-serif);
  font-size: 2rem;
  font-weight: 600;
}

.plan .price small {
  font-family: var(--font-ui);
  font-size: 0.9rem;
  color: var(--muted);
  font-weight: 400;
}

.plan .note { color: var(--muted); font-size: 0.9rem; margin: 0; }

.pricing-fineprint {
  color: var(--muted);
  font-size: 0.82rem;
  max-width: 52rem;
  margin-top: 2.5rem;
}

/* ---------- FAQ ---------- */

.faq details {
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
  background: var(--surface);
  margin-bottom: 12px;
  padding: 0 18px;
}

.faq summary {
  cursor: pointer;
  padding: 15px 0;
  font-weight: 600;
  list-style: none;
  position: relative;
  padding-right: 28px;
}

.faq summary::-webkit-details-marker { display: none; }

.faq summary::after {
  content: "+";
  position: absolute;
  right: 2px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--muted);
  font-size: 1.2rem;
}

.faq details[open] summary::after { content: "–"; }

.faq details p {
  margin: 0 0 16px;
  color: var(--muted);
  font-size: 0.98rem;
}

/* Lists inside an answer need the same bottom gap a <p> gets, or the last item
   sits flush against the details border when the panel is open. */
.faq details ul {
  margin: 0 0 16px;
  padding-left: 1.2em;
}

.faq details li {
  color: var(--muted);
  font-size: 0.98rem;
  margin-bottom: 0.4em;
}

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

.site-footer {
  border-top: 1px solid var(--line);
  padding: 40px 0 48px;
  font-size: 0.9rem;
  color: var(--muted);
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
  margin-bottom: 16px;
}

.footer-links a { color: var(--muted); }
.footer-links a:hover { color: var(--ink); }

.legal-note { font-size: 0.8rem; max-width: 52rem; margin: 0; }
.legal-note + .legal-note { margin-top: 0.6em; }

/* ---------- Long-form legal / support pages ---------- */

/* Same column as .prose below it, and only the top padding: the shorthand this
   used to be zeroed .container's side gutter, so the title sat flush against the
   screen edge on a phone and left of the text on a desktop. */
.page-title { padding-top: 56px; max-width: 62ch; }
.page-title .updated { color: var(--muted); font-size: 0.9rem; }

.prose {
  max-width: 62ch;
  padding-top: 24px;
  padding-bottom: 72px;
}

.prose h2 { font-size: 1.35rem; margin-top: 2.2em; }
.prose h3 { margin-top: 1.8em; }
.prose p, .prose li { color: var(--muted); }
.prose strong { color: var(--ink); }
.prose ul { padding-left: 1.2em; }
.prose li { margin-bottom: 0.5em; }

.prose .faq details p { font-size: 0.95rem; }

/* ---------- 404 ---------- */

.notfound {
  min-height: 55vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: center;
}
