/* droidactor.github.io — shared stylesheet for every page.
   Self-contained: no external CDN, font or import. Kept as one file so the pages
   (root + /ko/, product pages, manuals, and the blog) never drift apart. */

:root {
  --bg: #0d1117;
  --bg-soft: #161b22;
  --bg-card: #12171f;
  --line: #262d38;
  --fg: #e6edf3;
  --fg-dim: #9aa7b4;
  --fg-faint: #6e7b8a;
  --accent: #3ddc97;
  --accent-dim: #1f7a58;
  --warn: #d9a55b;
  /* The six colours of the "Dotori" wordmark — 빨 주 노 초 파 보. See .dotori below. */
  --dot-1: #ff7b72;
  --dot-2: #ffa657;
  --dot-3: #e3b341;
  --dot-4: #3fb950;
  --dot-5: #58a6ff;
  --dot-6: #d2a8ff;
  --radius: 12px;
}
@media (prefers-color-scheme: light) {
  :root {
    --bg: #ffffff;
    --bg-soft: #f6f8fa;
    --bg-card: #ffffff;
    --line: #d8dee4;
    --fg: #1f2328;
    --fg-dim: #57606a;
    --fg-faint: #7d8590;
    --accent: #0f7b52;
    --accent-dim: #a7e8cb;
    --warn: #9a6700;
    /* Darkened so every one of the six clears 4.5:1 on white — yellow especially. */
    --dot-1: #cf222e;
    --dot-2: #bc4c00;
    --dot-3: #9a6700;
    --dot-4: #1a7f37;
    --dot-5: #0969da;
    --dot-6: #8250df;
  }
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 16px/1.65 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        "Helvetica Neue", "Apple SD Gothic Neo", "Malgun Gothic", "Noto Sans KR", sans-serif;
}
.wrap { max-width: 880px; margin: 0 auto; padding: 0 20px; }

header.top {
  position: sticky; top: 0; z-index: 10;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}
@supports not (background: color-mix(in srgb, red 50%, transparent)) {
  header.top { background: var(--bg); }
}
.top .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; min-height: 56px;
}
.brand { font-weight: 700; letter-spacing: -0.01em; }
.brand a { color: inherit; text-decoration: none; }
.brand span { color: var(--accent); }

/* ---- "Dotori" wordmark --------------------------------------------------- */
/* The product-name prefix is painted in the six colours of 빨주노초파보. The word is
   deliberately NOT split into per-letter elements: the text node stays whole, so a
   crawler, a translator or a screen reader still reads one word, "Dotori". The colours
   therefore arrive as a gradient clipped to the glyphs.
   Stops sit on the letter boundaries rather than at even sixths, because D is wide and i
   is narrow — even sixths would cut letters in half. The boundaries are the measured
   cumulative advance widths of D-o-t-o-r-i. Weight matters as much as family here: 56 of
   the 281 places this class is used sit inside h1/h3/strong, and bold shifts every
   boundary left. Measured across what the stack at the top of this file actually resolves
   to on Windows — Segoe UI in three weights, Malgun Gothic for the Korean pages, and
   Arial as the final sans-serif fallback:
       Segoe UI           25.03  45.94  58.03  78.95  91.36
       Segoe UI Semibold  24.70  45.26  57.70  78.26  91.01
       Segoe UI Bold      24.32  44.49  57.33  77.50  90.62
       Malgun Gothic      25.08  46.03  58.08  79.03  91.39
       Malgun Gothic Bold 24.55  44.95  57.60  78.01  90.96
       Arial              27.07  47.92  58.34  79.19  91.67
       Arial Bold         24.53  45.28  56.59  77.34  90.56
   Each seam is a blend wide enough to hold the whole spread of those seven, so none of
   them puts a hard edge inside a letter. The second seam opens at 44% rather than an even
   44.5% for one reason: Segoe UI Bold's 44.49 sits right on that line.
   -apple-system (SF Pro) and Roboto carry the other platforms and are not installed here,
   so they are unmeasured. The seams are wide enough that they should land inside, but
   that is an expectation rather than a measurement. Fonts outside this stack are not a
   consideration — Calibri, Tahoma and Verdana all drift past these seams, and none of
   them can be selected by the stack above.
   Everything sits inside @supports because without background-clip:text the transparent
   fill would make the word vanish; unsupported browsers just inherit the text colour. */
@supports ((background-clip: text) or (-webkit-background-clip: text)) {
  .dotori {
    background-image: linear-gradient(90deg,
      var(--dot-1)    0%, var(--dot-1) 23.5%,
      var(--dot-2) 28.5%, var(--dot-2)   44%,
      var(--dot-3) 49.5%, var(--dot-3) 55.5%,
      var(--dot-4) 60.5%, var(--dot-4) 76.5%,
      var(--dot-5) 81.5%, var(--dot-5) 89%,
      var(--dot-6)   94%, var(--dot-6) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
  }
  /* Windows high contrast and print both discard the painted background, which would
     leave a transparent — invisible — word. Hand the text back its own colour there. */
  @media (forced-colors: active), print {
    .dotori {
      background-image: none;
      color: inherit;
      -webkit-text-fill-color: currentColor;
    }
  }
}

/* 한국어 로켈의 브랜드는 앱과 같은 빨강·노랑·파랑을 글자 단위로 쓴다.
   글자를 실제 span으로 나눠 gradient 경계가 한글 획 한가운데 걸리지 않게 한다. */
.dotori-ko { white-space: nowrap; }
.dotori-ko > span:nth-child(1) { color: #ff8a80; }
.dotori-ko > span:nth-child(2) { color: #ffe082; }
.dotori-ko > span:nth-child(3) { color: #90caf9; }
@media (prefers-color-scheme: light) {
  .dotori-ko > span:nth-child(1) { color: #b71c1c; }
  .dotori-ko > span:nth-child(2) { color: #6b5800; }
  .dotori-ko > span:nth-child(3) { color: #0d47a1; }
}
@media (forced-colors: active), print {
  .dotori-ko > span { color: inherit; }
}

/* ---- language links (real URLs, not a JS toggle) ------------------------- */
.langs { display: flex; gap: 4px; }
.lang-btn {
  font: inherit; font-size: 13px; line-height: 1;
  padding: 6px 10px; text-decoration: none;
  background: transparent; color: var(--fg-dim);
  border: 1px solid var(--line); border-radius: 999px;
}
.lang-btn[aria-current="page"] {
  color: var(--bg); background: var(--accent); border-color: var(--accent);
  font-weight: 600;
}

/* ---- hero --------------------------------------------------------------- */
.hero { padding: 56px 0 40px; border-bottom: 1px solid var(--line); }
.hero h1 { margin: 0 0 12px; font-size: clamp(28px, 5vw, 40px); line-height: 1.2; letter-spacing: -0.02em; }
.hero p { margin: 0; max-width: 60ch; color: var(--fg-dim); font-size: 17px; }

section { padding: 44px 0; border-bottom: 1px solid var(--line); }
section:last-of-type { border-bottom: 0; }
h2 {
  margin: 0 0 6px; font-size: 13px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.12em; color: var(--accent);
}
h2 + .lead { margin: 0 0 26px; color: var(--fg-dim); font-size: 15px; }
/* Most product-page sections have no .lead, so give whatever follows the label the same
   breathing room the .lead would have provided (6px + 20px = the 26px above). */
h2 + :not(.lead) { margin-top: 20px; }
h3 { margin: 30px 0 8px; font-size: 18px; letter-spacing: -0.01em; }
h3:first-of-type { margin-top: 0; }
p { margin: 0 0 14px; }
a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }

/* ---- app cards ---------------------------------------------------------- */
.cards { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); }
.card {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 18px 18px 16px;
  display: flex; flex-direction: column;
}
.card .icon { font-size: 26px; line-height: 1; margin-bottom: 10px; }
.card h3 { margin: 0 0 4px; font-size: 17px; }
.card h3 a { text-decoration: none; }
.card h3 a:hover { text-decoration: underline; }
.card .pkg {
  font-family: ui-monospace, SFMono-Regular, "Cascadia Mono", Consolas, monospace;
  font-size: 11.5px; color: var(--fg-faint); word-break: break-all; margin-bottom: 10px;
}
.card .desc { margin: 0 0 14px; font-size: 14.5px; color: var(--fg-dim); flex: 1; }
.card .foot { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 12.5px; }
.badge {
  display: inline-block; padding: 3px 9px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--fg-faint); font-size: 12px;
}
.badge.soon { border-color: var(--accent-dim); color: var(--accent); }
.badge.dev { border-color: var(--warn); color: var(--warn); }
.card .foot a { font-size: 12.5px; }

/* ---- Google Play badge -------------------------------------------------- */
/* Official artwork from play.google.com/intl/<lang>/badges/, self-hosted in assets/ and
   used unmodified — Google's badge guidelines forbid recolouring, cropping, stretching or
   lifting the logo out of it. So only the rendered height is set here; the PNG carries its
   own clear space, which is why nothing adds padding around it. The -en asset goes on the
   English tree and -ko on /ko/, matching the page language. This is a separate class from
   .badge above, which is this site's own status chip. */
.play-badge { display: inline-block; line-height: 0; }
.play-badge img { height: 44px; width: auto; }
.card .foot .play-badge img { height: 34px; }

/* ---- tables ------------------------------------------------------------- */
.scroll { overflow-x: auto; margin: 0 0 18px; }
table { border-collapse: collapse; width: 100%; min-width: 520px; font-size: 14.5px; }
th, td { text-align: left; padding: 9px 12px; border-bottom: 1px solid var(--line); vertical-align: top; }
th { color: var(--fg-dim); font-weight: 600; font-size: 13px; white-space: nowrap; }
td code, p code, li code {
  font-family: ui-monospace, SFMono-Regular, "Cascadia Mono", Consolas, monospace;
  font-size: 12.5px; background: var(--bg-soft); border: 1px solid var(--line);
  border-radius: 5px; padding: 1px 5px;
}

ul { margin: 0 0 14px; padding-left: 22px; }
li { margin-bottom: 8px; }
li::marker { color: var(--fg-faint); }

.note {
  background: var(--bg-soft); border: 1px solid var(--line);
  border-left: 3px solid var(--accent); border-radius: 8px;
  padding: 14px 16px; margin: 0 0 18px; font-size: 14.5px;
}
.note p:last-child { margin-bottom: 0; }
.note strong { color: var(--fg); }

.policy { border-top: 1px solid var(--line); padding-top: 20px; margin-top: 26px; }
.policy:first-of-type { border-top: 0; padding-top: 0; margin-top: 0; }
.policy h3 { margin-top: 0; }
.policy h3 .pkg-inline {
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 12px; font-weight: 400; color: var(--fg-faint); margin-left: 8px;
}

footer { padding: 34px 0 60px; color: var(--fg-faint); font-size: 13.5px; }
footer p { margin: 0 0 6px; }
/* Trademark attribution required on any page that shows the Google Play badge. */
footer .tm { margin-top: 12px; font-size: 12px; }
:target { scroll-margin-top: 72px; }

/* ---- product pages ------------------------------------------------------ */
.crumb { padding: 18px 0 0; font-size: 13px; color: var(--fg-faint); }
.crumb a { color: var(--fg-dim); }
/* The bare <span> here is the "/" separator. .dotori is excluded because the trail ends
   in the product name, and a margin there would push "Dotori" off its own word. */
.crumb > span:not(.dotori):not(.dotori-ko) { margin: 0 6px; }

.hero.product { padding: 26px 0 36px; }
.hero.product .icon { font-size: 40px; line-height: 1; margin-bottom: 14px; }
.hero.product .pkg {
  font-family: ui-monospace, SFMono-Regular, "Cascadia Mono", Consolas, monospace;
  font-size: 12.5px; color: var(--fg-faint); word-break: break-all; margin: 0 0 16px;
}
.hero.product .status { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 20px; }

.feature { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.feature > div {
  background: var(--bg-card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px 18px;
}
.feature h3 { margin: 0 0 6px; font-size: 15.5px; }
.feature p { margin: 0; font-size: 14.5px; color: var(--fg-dim); }

.spec { font-size: 14.5px; }
.spec th { width: 34%; }

.also { display: flex; flex-wrap: wrap; gap: 8px; }
.also a {
  display: inline-block; padding: 6px 12px; font-size: 13.5px; text-decoration: none;
  background: var(--bg-soft); border: 1px solid var(--line); border-radius: 999px;
}
.also a:hover { border-color: var(--accent-dim); }

/* ---- blog: post list ---------------------------------------------------- */
.posts { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.posts li {
  margin: 0; padding: 16px 18px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius);
}
.posts li.empty {
  background: none; border-style: dashed;
  color: var(--fg-faint); font-size: 14.5px;
}
.posts h3 { margin: 0 0 6px; font-size: 17px; }
.posts h3 a { text-decoration: none; }
.posts h3 a:hover { text-decoration: underline; }
.posts p:last-child { margin: 0; font-size: 14.5px; color: var(--fg-dim); }
.posts .meta, .post-meta { font-size: 12.5px; color: var(--fg-faint); }
.posts .meta { margin: 0 0 6px; }
.post-meta { margin: 0; }

/* ---- blog: post body ----------------------------------------------------- */
/* A post is prose, so its headings are real headings — not the small uppercase
   section labels the product pages use for h2. */
.post-body { padding: 34px 0 8px; }
.post-body h2 {
  margin: 34px 0 10px; font-size: 21px; font-weight: 700;
  text-transform: none; letter-spacing: -0.01em; color: var(--fg);
}
.post-body > h2:first-child { margin-top: 0; }
.post-body h3 { margin: 24px 0 8px; font-size: 16.5px; }
.post-body > :last-child { margin-bottom: 0; }
.post-app {
  display: flex; align-items: center; gap: 16px;
  margin: 20px 0 24px; padding: 16px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius);
}
/* `>` on purpose: the card can also hold a Google Play badge, and that image must keep
   its own 646x250 aspect instead of being cropped into the 88px app-icon square. */
.post-app > img {
  flex: 0 0 auto; width: 88px; height: 88px;
  border-radius: 22%; object-fit: cover;
}
.post-app p { margin: 0; color: var(--fg-dim); font-size: 14.5px; }
.post-app strong { display: block; margin-bottom: 3px; color: var(--fg); font-size: 17px; }
/* Wrapper used only when the card carries a store badge, so the text and the badge stack
   vertically inside the second flex item. Posts without a badge keep <p> as that item. */
.post-app-text { min-width: 0; }
.post-app-text .play-badge { margin-top: 10px; }
.post-app-text .play-badge img { height: 38px; }
/* On posts with a store badge the whole card is one link, so .post-app is an <a> there and
   the badge inside is a plain <span> — nesting a second <a> is not allowed. Every text
   colour is set on the descendants above, so the accent link colour never reaches the card
   and only the underline has to be switched off. Posts without a badge keep a <div>, which
   is why the hover cue is scoped to a.post-app rather than to .post-app. */
a.post-app { text-decoration: none; }
a.post-app:hover { border-color: var(--accent-dim); }
.screenshot-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start; gap: 14px; margin: 18px 0 24px;
}
.screenshot-grid figure {
  display: flex; flex-direction: column; justify-content: flex-start;
  min-width: 0; margin: 0; padding: 10px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius);
}
.screenshot-grid img {
  display: block; width: 100%; height: auto; max-height: 680px;
  object-fit: contain; border-radius: 8px; background: #05080c;
}
/* A shot may link to the store listing. Block so the inline baseline gap under the image
   disappears; the ring makes the shot read as clickable without moving the grid. */
.screenshot-grid a { display: block; border-radius: 8px; }
.screenshot-grid a:hover img,
.screenshot-grid a:focus-visible img { outline: 2px solid var(--accent); outline-offset: 2px; }
.screenshot-grid figcaption {
  padding: 9px 2px 1px; color: var(--fg-dim); font-size: 13px; line-height: 1.45;
}
@media (max-width: 600px) {
  .post-app { align-items: flex-start; }
  .post-app > img { width: 72px; height: 72px; }
  .screenshot-grid { grid-template-columns: 1fr; }
}
pre {
  margin: 0 0 16px; padding: 12px 14px; overflow-x: auto;
  background: var(--bg-soft); border: 1px solid var(--line); border-radius: 8px;
  font-family: ui-monospace, SFMono-Regular, "Cascadia Mono", Consolas, monospace;
  font-size: 13px; line-height: 1.55;
}
pre code { background: none; border: 0; padding: 0; font-size: inherit; }

/* ---- manuals ------------------------------------------------------------- */
.manual-hero { padding-bottom: 32px; }
.manual-meta { margin-top: 12px !important; color: var(--fg-faint) !important; font-size: 13px !important; }
.manual-toc {
  margin: 28px 0 4px; padding: 18px 20px;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: var(--radius);
}
.manual-toc strong { display: block; margin-bottom: 8px; }
.manual-toc ol { margin: 0; padding-left: 22px; columns: 2; column-gap: 32px; }
.manual-toc li { break-inside: avoid; margin-bottom: 5px; }
.manual-body { padding-top: 20px; }
.manual-body h2 { scroll-margin-top: 72px; }
.manual-steps { margin: 14px 0 22px; padding-left: 28px; }
.manual-steps > li { padding-left: 6px; margin-bottom: 18px; }
.manual-steps > li::marker { color: var(--accent); font-weight: 700; }
.manual-steps h3 { margin: 0 0 5px; }
.manual-steps p:last-child { margin-bottom: 0; }
.manual-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  margin: 20px 0 4px;
}
.manual-actions > a:not(.play-badge) {
  display: inline-block; padding: 8px 13px; text-decoration: none;
  background: var(--bg-soft); border: 1px solid var(--line); border-radius: 8px;
}
.manual-actions > a:not(.play-badge):hover { border-color: var(--accent-dim); }
.manual-shot { margin: 18px auto 24px; max-width: 440px; }
.manual-shot img {
  display: block; width: 100%; height: auto; max-height: 720px; object-fit: contain;
  border: 1px solid var(--line); border-radius: var(--radius); background: #05080c;
}
.manual-shot figcaption { padding: 8px 2px 0; color: var(--fg-dim); font-size: 13px; }
.troubleshooting th:first-child { width: 28%; }
@media (max-width: 600px) {
  .manual-toc ol { columns: 1; }
}
