/* connect.openab.dev — light theme, palette drawn from the app icon rather than
   invented: the mint of the squircle, the blue and pink of the jellyfish.
   Follows the structure foldic.app uses, including the dark-mode override, so the
   two sites are recognisably from the same hand. */
:root {
  /* Sampled from the app icon rather than chosen: the squircle fill is #D6F0F2,
     and the page tones are that colour mixed toward white. Using the fill at full
     strength behind body text reads as a coloured box and drops the contrast, so
     --bg is the palest relative of it and --tint the closest. */
  --mint: #7FC8BC;
  --mint-deep: #1B4A46;
  --mint-tint: #DCF2F4;
  --brush: rgba(127, 200, 188, 0.62);
  --blue: #5B9BD5;
  --pink: #E88FB4;
  --ink: #16302E;
  --muted: #59736F;
  --bg: #EDF8F9;
  --card: #E4F5F7;
  --border: rgba(27, 74, 70, 0.15);
  --shadow: 0 24px 80px rgba(22, 48, 46, 0.16);
}
@media (prefers-color-scheme: dark) {
  :root {
    --mint: #7FC8BC;
    --mint-deep: #A8E0D6;
    --mint-tint: #12302F;
    --brush: rgba(127, 200, 188, 0.42);
    --ink: #E6F2F1;
    --muted: #90A8A5;
    --bg: #0D1717;
    --card: #142020;
    --border: rgba(127, 200, 188, 0.2);
    --shadow: 0 24px 80px rgba(0, 0, 0, 0.5);
  }
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: 16px/1.7 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--mint-deep); }

/* CJK typography, per language rather than one stack for all three.
   Two things differ from Latin and both need saying:
   - A Han glyph fills its em box, so at the same pixel size it reads smaller and
     denser than Latin. The headings are therefore larger, not merely translated.
   - The Latin heading uses negative tracking, which closes up Han strokes and
     makes them muddy. CJK gets tracking back to zero or slightly positive. */
html[data-lang="zh"] body {
  font-family: "PingFang TC", "Heiti TC", "Noto Sans TC", -apple-system,
               BlinkMacSystemFont, system-ui, sans-serif;
}
html[data-lang="ja"] body {
  font-family: "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Noto Sans JP",
               -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
}
html[data-lang="ko"] body {
  font-family: "Apple SD Gothic Neo", "Noto Sans KR", -apple-system,
               BlinkMacSystemFont, system-ui, sans-serif;
}

nav {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  max-width: 940px; margin: 0 auto; padding: 20px 24px;
}
nav .brand {
  display: flex; align-items: center; gap: 6px;
  font-weight: 700; text-decoration: none; color: var(--ink); font-size: 1rem;
  letter-spacing: -0.015em;
  /* Pinned, and not inherited. The per-language stacks are set on body, and
     "OpenAB Connect" is Latin — so the wordmark was being drawn with whichever CJK
     face the page happened to use for its Latin glyphs, and visibly changed shape on
     every language switch. A wordmark has to be one shape. Apple SD Gothic Neo is
     first because that is the rendering picked as the reference, on the Korean page. */
  font-family: "Apple SD Gothic Neo", -apple-system, BlinkMacSystemFont, "Segoe UI",
               system-ui, sans-serif;
}
/* The mark is set smaller than its intrinsic 28px box and given a slight negative
   offset so it optically aligns with the cap height of the wordmark rather than
   its line box, which is what made the pair look loose. */
nav .brand img { width: 24px; height: 24px; margin-top: -1px; }
nav .links { display: flex; align-items: center; gap: 1.1rem; flex-wrap: wrap; font-size: 0.95rem; }
nav .links a { text-decoration: none; color: var(--muted); }
nav .links a:hover { color: var(--ink); }
nav .lang { margin-left: 0.6rem; font-size: 0.9rem; color: var(--muted); }
nav .lang a { margin: 0 0.15rem; text-decoration: none; color: var(--muted); }
nav .lang a.active { color: var(--ink); font-weight: 700; }
@media (max-width: 620px) { nav .lang { margin-left: 0; } }

.wrap { max-width: 780px; margin: 0 auto; padding: 0 24px 72px; }
/* Every top-level section carries its own width now that .wrap is no longer in
   these pages. text-align alone centred the text but left the measure to the
   viewport, so a wide monitor stretched the headline and a phone let it touch
   the edges. */
header { max-width: 1040px; margin: 0 auto; padding: 48px 24px 8px; text-align: center; }
header img.appicon { width: 104px; height: 104px; }
/* clamp rather than a fixed size plus a breakpoint: the hero is two lines fixed by a
   <br>, so its width is driven entirely by font-size, and a single desktop value is
   either timid on a large display or overflowing on a small one. */
h1 {
  font-size: clamp(2.2rem, 5.6vw, 3.4rem); font-weight: 800;
  margin: 22px 0 10px; letter-spacing: -0.022em; line-height: 1.2;
}
.tag { color: var(--muted); font-size: 1.16rem; margin: 0 auto; max-width: 34em; }

/* The explicit <br> in each hero fixes the break at a clause boundary, but a narrow
   viewport wraps again below it, and CJK breaks between any two characters — which
   is how 「它們繼續跑。」 ended up with 「跑。」 alone on a line. balance evens the
   line lengths instead of filling greedily, so the last line is never one glyph. */
h1, .tag { text-wrap: balance; }
/* Keep the second half whole rather than letting it split mid-clause. inline-block
   moves the whole run down instead of breaking inside it; it can still wrap
   internally if the viewport is genuinely narrower than the run, so nothing
   overflows. */
.tag strong { display: inline-block; }

/* The CJK hero is deliberately bigger and heavier than the Latin one. Han glyphs
   carry more ink per character, so a headline that is merely translated ends up
   looking timid beside the English. Weight 800 lands on PingFang TC Semibold and
   Hiragino Sans W6, which are the heaviest faces reliably present on macOS —
   synthetic bold on Han strokes smears them, so this asks for a real weight. */
html[data-lang="zh"] h1,
html[data-lang="ja"] h1,
html[data-lang="ko"] h1 {
  font-size: clamp(2.1rem, 5vw, 3rem);
  letter-spacing: 0.01em;
  line-height: 1.28;
}
html[data-lang="zh"] .tag,
html[data-lang="ja"] .tag,
html[data-lang="ko"] .tag {
  font-size: 1.2rem;
  line-height: 1.75;
  max-width: 26em;
}
html[data-lang="zh"] h2,
html[data-lang="ja"] h2,
html[data-lang="ko"] h2 { font-size: 1.35rem; font-weight: 700; }

h2 { font-size: 1.15rem; margin: 40px 0 12px; }
h3 { font-size: 1rem; margin: 22px 0 6px; }
.grad {
  background: linear-gradient(90deg, var(--mint), var(--blue), var(--pink));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.panel {
  background: var(--card); border: 1px solid var(--border);
  border-radius: 12px; padding: 20px 22px; margin: 20px 0;
}
.note { border-left: 3px solid var(--mint); padding-left: 14px; color: var(--muted); }
code, pre { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.9em; }
pre {
  background: var(--mint-tint); border: 1px solid var(--border);
  border-radius: 10px; padding: 14px 16px; overflow-x: auto; color: var(--mint-deep);
}
ul { padding-left: 1.2em; } li { margin: 7px 0; }
.dim { color: var(--muted); }
figure { margin: 30px 0 8px; }
/* The window in the capture has its own light chrome — a white title bar and an
   #F3F3F3 sidebar — so setting it directly on the mint page put two unrelated light
   tones against each other, with a dark 1px border drawn between them for good
   measure. Instead the figure is a white card and the image is inset in it: the card's
   gutter meets the window's own chrome, so that boundary disappears, and the card
   against the mint page is a deliberate edge rather than a near-miss.
   The card stays light under prefers-color-scheme: dark, because the screenshot itself
   is light and a dark card would reintroduce the mismatch it exists to remove. */
/* No radius here. The capture is masked to the window's own 71px corner with the card
   colour outside it, so the curve is already in the pixels; a CSS radius on top would
   clip that curve a second time at a different value. */
figure img { width: 100%; height: auto; display: block; }
.shotwrap figure {
  margin: 0; background: #FFFFFF;
  padding: 10px; border-radius: 16px;
  box-shadow: 0 18px 60px rgba(22, 48, 46, 0.14), 0 1px 0 rgba(22, 48, 46, 0.06);
}
figcaption { color: var(--muted); font-size: 0.9rem; margin-top: 12px; }
footer {
  max-width: 1080px; margin: 56px auto 0; padding: 26px 24px 48px;
  border-top: 1px solid var(--border);
  color: var(--muted); font-size: 0.9rem;
  display: flex; gap: 20px; flex-wrap: wrap;
  justify-content: center; align-items: center;
}
.date { color: var(--muted); margin: 0 0 30px; }

/* Brush highlight on the phrase the headline turns on. The band stops at 94% so it
   reads as a marker stroke rather than a filled background, and starts at 58% so
   it clears the x-height of Latin and the body of Han glyphs alike. */
.mark {
  background: linear-gradient(transparent 58%, var(--brush) 58%,
                              var(--brush) 94%, transparent 94%);
  padding: 0 0.08em;
}

/* Feature blocks. Same grammar as foldic.app: auto-fit grid, card background, a
   tinted icon tile. The icons are inline SVG rather than an icon font or emoji so
   they inherit --mint-deep and stay crisp at any scale. */
section.features { max-width: 1080px; margin: 0 auto; padding: 3rem 24px 0; }
.features-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(268px, 1fr)); gap: 1.1rem;
}
.feature {
  background: var(--card); border: 1px solid var(--border);
  border-radius: 18px; padding: 1.5rem 1.6rem;
}
.feature .icon {
  width: 42px; height: 42px; border-radius: 11px; background: var(--mint-tint);
  display: flex; align-items: center; justify-content: center; margin-bottom: 0.9rem;
}
.feature .icon svg {
  width: 22px; height: 22px; stroke: var(--mint-deep); fill: none;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.feature h3 { margin: 0 0 0.4rem; font-size: 1.02rem; }
.feature p { margin: 0; color: var(--muted); font-size: 0.95rem; line-height: 1.65; }
html[data-lang="zh"] .feature h3,
html[data-lang="ja"] .feature h3,
html[data-lang="ko"] .feature h3 { font-size: 1.12rem; font-weight: 700; }

/* The screenshot earns more width than the reading column: it is the only place
   the product is actually visible. */

/* A terminal product's screenshot is mostly dark, and it always will be — the agent
   CLIs draw ANSI colour tuned for a dark background. So rather than fighting it, the
   showcase band tints toward the icon colour and fades out, which makes the dark
   window read as deliberately inset instead of pasted onto the page. */
/* No background here. A tint on this element is 1080px wide and centred, so it ends
   in a hard vertical edge against the page on both sides — which is exactly the
   stray colour block it looked like. The card and its shadow already seat the
   screenshot; the band was doing that job twice and badly. */
.shotwrap { max-width: 1080px; margin: 0 auto; padding: 24px 24px 8px; }
/* The capture is cropped to the window itself, with the macOS drop shadow removed.
   That shadow is dark and desaturated, so compositing it onto the mint page produced
   a grey ring that read as a mismatched frame — and CSS was drawing a second shadow
   underneath it. One shadow, from CSS, which then tints correctly in both schemes. */

/* Ribbon on an unreleased card. A corner pill rather than a diagonal banner: the
   point is to be unmissable while reading as part of the card, because an unmarked
   roadmap item would put every other card's credibility on the footing of a plan. */
.feature { position: relative; }
.feature.soon { border-style: dashed; }
.feature .ribbon {
  position: absolute; top: 12px; right: 12px;
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--mint-deep); background: var(--mint-tint);
  border: 1px solid var(--border); border-radius: 999px; padding: 3px 9px;
}
.feature.soon h3, .feature.soon p { opacity: 0.78; }

/* FAQ. Same grammar as foldic.app: a bottom-ruled details list with +/- and a
   copyable anchor per question. */
section.faq { max-width: 760px; margin: 0 auto; padding: 3.5rem 24px 1rem; }
section.faq h2 { text-align: center; margin-bottom: 1.6rem; }
.faq details { border-bottom: 1px solid var(--border); padding: 1rem 0.2rem; }
/* The question text is wrapped in one span deliberately. summary is a flex
   container, so every inline element inside it — and these questions contain
   <code> — would otherwise become its own flex item and be pushed apart by
   space-between, scattering one sentence across the full width. */
.faq summary {
  cursor: pointer; font-weight: 600; font-size: 1rem; list-style: none;
  display: flex; align-items: baseline; gap: 0.1rem;
}
.faq summary .q { flex: 1 1 auto; }
.faq summary code { font-size: 0.92em; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; color: var(--mint-deep); font-size: 1.3rem; font-weight: 400;
  flex: 0 0 auto; margin-left: 0.6rem; line-height: 1;
}
.faq details[open] summary::after { content: "–"; }
.faq summary .faq-anchor {
  margin-left: 0.4rem; color: var(--mint-deep); flex: 0 0 auto;
  opacity: 0.3; text-decoration: none; font-weight: 400; transition: opacity 0.15s;
}
.faq summary .faq-anchor:hover, .faq summary .faq-anchor:focus { opacity: 1; }
.faq details .a { padding-top: 0.6rem; }
.faq details p { color: var(--muted); font-size: 0.95rem; margin: 0 0 0.7rem; }
.faq details p:last-child { margin-bottom: 0; }
/* A two-sided comparison is a list, so it is marked up as one. The markers are
   suppressed and replaced by indentation because the two items are peers being
   contrasted, not steps or a tally. */
.faq details ul { list-style: none; margin: 0 0 0.8rem; padding: 0; }
.faq details ul li {
  color: var(--muted); font-size: 0.95rem; margin: 0 0 0.55rem;
  padding-left: 0.95rem; border-left: 2px solid var(--border);
}
.faq details ul li:last-child { margin-bottom: 0; }
.faq details ul li strong { color: var(--ink); }
html[data-lang="zh"] .faq summary,
html[data-lang="ja"] .faq summary,
html[data-lang="ko"] .faq summary { font-size: 1.06rem; font-weight: 700; }
html[data-lang="zh"] .faq details p,
html[data-lang="ja"] .faq details p,
html[data-lang="ko"] .faq details p,
html[data-lang="zh"] .faq details ul li,
html[data-lang="ja"] .faq details ul li,
html[data-lang="ko"] .faq details ul li { font-size: 1rem; line-height: 1.85; }

/* The same badge as the unreleased card, set inline so it can sit in a question.
   A reader scanning closed summaries has to be able to tell a roadmap answer from a
   feature without opening it. */
.ribbon.inline {
  position: static; display: inline-block; vertical-align: 0.12em;
  margin-left: 0.45rem; font-size: 0.62rem;
}
.faq summary .q .ribbon.inline { font-weight: 700; }
.faq details a { color: var(--mint-deep); }
