/*
 * The site wears the app's theme.
 *
 * Every colour here names a **semantic** slot from `tokens.css` (`--c-*`), never a
 * primitive and never a literal — the same law the app keeps, for the same reason: the day
 * the theme moves, a component that named a primitive is the one spot that does not move
 * with it. `tokens.css` is generated in the app repo by `node tools/tokens.mjs` and copied
 * here by `npm run sync`; do not edit it.
 *
 * Three things the app's look cannot live with, absent here too: `border-radius`, soft
 * shadows and gradients. A double border is `box-shadow: inset 0 0 0 1px`; a lifted one is
 * a hard `3px 3px 0`.
 *
 * **Dot type for the chrome, a normal face for the prose.** The app is drawn at 16-dot
 * grids where every glyph is a bitmap, and that is right for a speech bubble. A landing
 * page is several hundred words of reading, and a bitmap face at paragraph length is
 * tiring — so NeoDunggeunmo carries the wordmark, the headings and the buttons, and the
 * body is whatever the reader's system draws well.
 */

@font-face {
  font-family: 'neodgm';
  src: url('/fonts/neodgm.woff2') format('woff2');
  font-display: swap;
  /* Latin-1 and every Hangul syllable — which is exactly the two languages this site has. */
}

:root {
  --dot: 2px;
  --page: 1120px;
  --read: 68ch;
  --pixel: 'neodgm', ui-monospace, monospace;
  --prose: ui-sans-serif, system-ui, 'Segoe UI', 'Pretendard', 'Apple SD Gothic Neo',
    'Malgun Gothic', sans-serif;
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--c-surface-deep);
  color: var(--c-text-body);
  font-family: var(--prose);
  font-size: 17px;
  line-height: 1.65;
}

img { max-width: 100%; height: auto; display: block; image-rendering: pixelated; }

/* --c-accent is the one gold that carries text on BOTH palettes. --c-accent-hi is the
   brighter one: a highlight against the dark navy, and washed out on parchment (gold on
   gold, about 3:1). It is used for hover on a dark ground only, never for reading. */
a { color: var(--c-accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--c-text-body); }

code {
  font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
  font-size: .92em;
  background: var(--c-surface-sunken);
  padding: 0 var(--sp-2);
}

h1, h2, h3, .mark, .btn, .big, .tag {
  font-family: var(--pixel);
  font-weight: 400;
  letter-spacing: .01em;
}

h1 { font-size: clamp(30px, 6vw, 52px); line-height: 1.25; margin: 0 0 var(--sp-12); }
h2 { font-size: clamp(21px, 3vw, 28px); line-height: 1.35; margin: var(--sp-24) 0 var(--sp-8); }
h3 { font-size: 19px; margin: var(--sp-16) 0 var(--sp-4); }

p { margin: 0 0 var(--sp-12); max-width: var(--read); }
.lead { font-size: 20px; color: var(--c-text-body); }
.small { font-size: 14px; }
.faint { color: var(--c-text-faint); }

/* The 16px gutter is not decoration — below it, a phone clips the first letter. */
.wrap { width: 100%; max-width: var(--page); margin: 0 auto; padding: 0 16px; }

.skip {
  position: absolute; left: -9999px;
  background: var(--c-accent); color: var(--c-text-on-accent); padding: var(--sp-4) var(--sp-8);
}
.skip:focus { left: var(--sp-8); top: var(--sp-8); z-index: 9; }

/* ───────────────────────────────────────────────────────────────────────── the bar */

.bar {
  border-bottom: 1px solid var(--c-edge-inner);
  background: var(--c-surface-base);
  position: sticky; top: 0; z-index: 5;
}
.bar .wrap { display: flex; align-items: center; gap: var(--sp-8); min-height: 56px; flex-wrap: wrap; }
.mark {
  font-size: 22px; color: var(--c-accent); text-decoration: none; margin-right: auto;
}
.bar nav { display: flex; gap: var(--sp-8); flex-wrap: wrap; }
.bar nav a, .lang {
  font-family: var(--pixel); font-size: 16px; text-decoration: none;
  color: var(--c-text-soft); padding: var(--sp-2) var(--sp-4);
}
.bar nav a:hover, .lang:hover { color: var(--c-accent); }
.bar nav a.on { color: var(--c-accent); box-shadow: inset 0 -2px 0 var(--c-accent); }
.lang { color: var(--c-text-faint); border-left: 1px solid var(--c-edge-inner); padding-left: var(--sp-8); }

/* ───────────────────────────────────────────────────────────────────── the sections */

.hero { padding: clamp(40px, 9vw, 96px) 0 var(--sp-24); }
.hero .lead { max-width: 42ch; font-size: clamp(18px, 2.4vw, 22px); }
.cta { display: flex; gap: var(--sp-8); flex-wrap: wrap; margin: var(--sp-16) 0 var(--sp-8); }

.btn {
  font-size: 17px; text-decoration: none; display: inline-block;
  padding: var(--sp-6) var(--sp-16);
  background: var(--c-accent); color: var(--c-text-on-accent);
  box-shadow: 3px 3px 0 var(--c-shadow-lift);
  border: 1px solid var(--c-edge-accent);
}
.btn:hover { background: var(--c-accent-hi); color: var(--c-text-on-accent); }
.btn:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--c-shadow-lift); }
.btn.ghost { background: transparent; color: var(--c-text-body); border-color: var(--c-edge-outer); }
.btn.ghost:hover { color: var(--c-accent-hi); border-color: var(--c-accent); }
.btn.big-btn { font-size: 21px; padding: var(--sp-10) var(--sp-24); }

.shot { padding: var(--sp-8) 0 var(--sp-24); }
/* The hero is one 1920-wide strip of a real taskbar. Boxed into the reading column it would
   be displayed at little more than half size and the dots would stop being square; edge to
   edge it lands near 1:1 on a 1920 screen, which is most of them. */
.bleed { width: 100%; max-width: 1920px; margin: 0 auto; }
.bleed .frame { border-left: 0; border-right: 0; padding-left: 0; padding-right: 0; box-shadow: none; }
.bleed figcaption { padding: 0 16px; }
.bleed.under { margin-top: var(--sp-24); }
.frame {
  margin: 0;
  background: var(--c-surface-base);
  border: 1px solid var(--c-edge-outer);
  box-shadow: inset 0 0 0 1px var(--c-edge-inner), 3px 3px 0 var(--c-shadow-lift);
  padding: var(--sp-6);
}
.frame img, .shot-video { width: 100%; height: auto; display: block; }
/* The panel shots are drawn at their own dot size; blown past it they go soft for nothing. */
.band .frame img { width: auto; max-width: 100%; margin: 0 auto; }
/* Pixel art through H.264: the decoder hands back the same hard-edged dots, so the browser
   must not smooth them on the way to the screen either. The dark ground shows while the
   poster loads, instead of a white flash on a dark page. */
.shot-video { image-rendering: pixelated; background: var(--c-surface-deep); }
.frame figcaption { margin-top: var(--sp-4); }

.three .wrap { display: grid; gap: var(--sp-12); grid-template-columns: repeat(3, 1fr); }
.three { padding: var(--sp-16) 0; }

.card {
  background: var(--c-surface-raised);
  border: 1px solid var(--c-edge-inner);
  padding: var(--sp-12);
}
.card h2 { margin-top: 0; font-size: 21px; }
.card p { margin-bottom: 0; }
.card.gold { border-color: var(--c-edge-accent); box-shadow: inset 0 0 0 1px var(--c-edge-accent); }

.band { padding: clamp(28px, 5vw, 64px) 0; border-top: 1px solid var(--c-edge-inner); }
.band.alt { background: var(--c-surface-sunken); }
.two { display: grid; gap: var(--sp-24); grid-template-columns: 1fr 1fr; align-items: center; }

.tag {
  font-size: 13px; vertical-align: middle; margin-left: var(--sp-4);
  padding: 0 var(--sp-4);
  color: var(--c-text-on-accent); background: var(--c-accent);
}

.price-strip { padding: clamp(28px, 5vw, 64px) 0; border-top: 1px solid var(--c-edge-inner); }
.big { font-size: 38px; color: var(--c-accent); margin: var(--sp-4) 0; }
.big .small { font-size: 16px; color: var(--c-text-faint); }

/* ────────────────────────────────────────────────────────────────── the inner pages */

.page { padding: clamp(28px, 5vw, 64px) 0 var(--sp-24); }
.page.narrow .wrap { max-width: 760px; }

.plans { display: grid; gap: var(--sp-12); grid-template-columns: 1fr 1fr; margin: var(--sp-16) 0; }
.plan {
  background: var(--c-surface-raised);
  border: 1px solid var(--c-edge-inner);
  padding: var(--sp-16);
}
.plan.gold { border-color: var(--c-edge-accent); box-shadow: inset 0 0 0 1px var(--c-edge-accent); }
.plan h2 { margin-top: 0; }

.ticks, .docs-list, .steps { padding-left: 0; list-style: none; max-width: var(--read); }
.ticks li, .docs-list li { padding-left: 22px; position: relative; margin-bottom: var(--sp-4); }
.ticks li::before, .docs-list li::before {
  /* A drawn mark, not a font glyph — the app's atlases have no tick either, and a face
     without one silently draws nothing. */
  content: ''; position: absolute; left: 0; top: .62em;
  width: 8px; height: 8px; background: var(--c-accent);
}
.steps { counter-reset: s; }
.steps li { counter-increment: s; padding-left: 30px; position: relative; margin-bottom: var(--sp-8); }
.steps li::before {
  content: counter(s); position: absolute; left: 0; top: 0;
  font-family: var(--pixel); color: var(--c-text-on-accent); background: var(--c-accent);
  width: 22px; height: 22px; text-align: center; line-height: 22px; font-size: 14px;
}

.faq { max-width: var(--read); }
.faq dt { font-weight: 600; margin-top: var(--sp-12); }
.faq dd { margin: var(--sp-2) 0 0; color: var(--c-text-soft); }

.grab { margin: var(--sp-16) 0 var(--sp-24); }
.code {
  background: var(--c-surface-sunken-deep);
  border: 1px solid var(--c-edge-inner);
  padding: var(--sp-8) var(--sp-12);
  overflow-x: auto;
  max-width: var(--read);
}
.code code { background: none; padding: 0; }

.warn {
  border: 1px solid var(--c-edge-accent);
  box-shadow: inset 0 0 0 1px var(--c-edge-accent);
  background: var(--c-surface-sunken);
  padding: var(--sp-12) var(--sp-16);
  margin: var(--sp-24) 0;
}
.warn h2 { margin-top: 0; font-size: 20px; color: var(--c-accent); }
.warn p:last-child { margin-bottom: 0; }

/* ──────────────────────────────────────────────────────────────────────── the foot */

.foot {
  border-top: 1px solid var(--c-edge-inner);
  background: var(--c-surface-base);
  padding: var(--sp-16) 0;
  margin-top: var(--sp-24);
}
.foot p { margin-bottom: var(--sp-2); color: var(--c-text-faint); }

/* ─────────────────────────────────────────────────────────────────────── the phone */

@media (max-width: 860px) {
  .three .wrap, .two, .plans { grid-template-columns: 1fr; }
  /* The picture goes under the words whichever side it was written on, so a section that
     put the image first does not open with an image and no reason to look at it. */
  .band.alt .two > .frame { order: 2; }
  .bar .wrap { min-height: 0; padding-top: var(--sp-6); padding-bottom: var(--sp-6); }
  .mark { width: 100%; margin-right: 0; }
  .lang { border-left: 0; padding-left: 0; margin-left: auto; }
  body { font-size: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
