/* ==========================================================================
   BeCozU — Manual (css/manual.css)
   Loaded only by manual/ (9 pages: the hub + 8 topic guides). Assumes
   core.css (tokens, .icon, header/footer chrome, the language switcher, the
   ribbon breadcrumb) is already loaded.

   This is not a marketing scroll. It is a documentation sub-site modelled on
   Apple's support guides: a table of contents that stays on screen, and a
   body column at a fixed reading measure. The previous version was a straight
   recolour of the light theme, which left three structural problems the new
   colours could not fix:

   1. Every step was a card — border, 32px padding, hover lift, 52px numbered
      disc, decorative corner wash. setting/ stacked ten of them. This site
      uses cards for objects (a bento stat, a research quote), never for one
      sentence of instruction, so ten in a column read as ten widgets where
      there should be one document.
   2. The measure was wrong in both directions at once. .manual-content had no
      max-width (904px), yet the instruction text inside a step was squeezed to
      371px — roughly 19 Korean characters a line — because the screenshot took
      42%. Meanwhile the screenshot only ever rendered 194px wide (max-height
      capped it), leaving 119px of empty frame, forty-four times over.
   3. The screenshot frame was var(--veil-3) — a 12%-white panel — justified in
      design.md as a "photographed, not painted" exception for bright app UI.
      The premise was false: every app capture in /assets/images/manual/** is a
      DARK-mode screenshot (near-black, white type, cyan/teal accents — natively
      on palette). Forty-two of the forty-four images were wrapped in a bright
      halo that inverted 제2원칙. There is no exception left at all: the two
      white-studio hardware stills that were the last of them are gone, replaced
      on troubleshooting/ by the reset clip, which shows the same action moving.

   Geometry, at --container-wide with the 24px gutter:
     1400 − 48        = 1352 shell
     1352 − 280 − 64  = 1008 available, capped to 960
     960 − 32 − 24 − 240 − 24 = 640 text column  (~34 KO / ~67 Latin chars)

   Desktop-first (max-width queries only) at design.md's 1024 / 768 / 640.
   ========================================================================== */

@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}

/* --------------------------------------------------------------------------
   Detail pages
   The topic pages are ordinary sub-pages now: .section + .container +
   .section-intro + .card-grid, exactly as about/, technology/ and app/ build
   theirs, with the ghost-numeral .step-card pages.css already draws for app/'s
   How to Use. The bespoke shell, the sticky TOC column and the prev/next pill
   pair are gone; what is left here is only what the shared vocabulary has no
   word for — a screenshot inside a step card, and the two callouts.
   -------------------------------------------------------------------------- */

/* A phone capture in a split-grid, opposite its instruction. .card-media dims
   and vignettes its media so photography sits back into the page; a screenshot
   is being read rather than looked at, so it keeps its own contrast and loses
   the vignette. Height-capped because the source is 1179x2556 and the column
   is half a container wide. */
.card-media-shot {
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  box-shadow: none;
  padding: var(--space-6);
  display: flex;
  justify-content: center;
}

.card-media-shot > img {
  filter: none;
  max-height: 460px;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  border-radius: var(--radius-xs);
}

.card-media-shot::after {
  display: none;
}

/* Precaution callout.
   This has now been three things. It started as a filled red slab, which put
   two pages in alarm colours before the reader had done anything. Stripping it
   to a bare rail fixed the alarm but left the text floating beside a line,
   reading like a stray pull-quote rather than part of the page.

   So: .tile's recipe — --veil-1 fill, --border-subtle hairline, --radius-md.
   That is the lightest contained surface this system owns, which is exactly
   what a callout wants: one object, no slab.

   The icon is an inline SVG carrying --status-caution, not the ⚠️ emoji the
   strings used to carry. The emoji had to go because it is a font glyph in a
   site that draws every icon itself, and its colour was outside our control.
   The yellow is deliberate and is NOT --accent-dawn: see that token's note in
   core.css. A cyan warning triangle is the same colour as every other accent
   on the page and therefore signals nothing. */
.callout {
  display: flex;
  gap: var(--space-4);
  max-width: var(--measure-read);
  margin: 0 0 var(--space-9);
  padding: var(--space-5);
  background: var(--veil-1);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}

.callout .icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  /* Optical: sit on the first line of text, not the top of the box. */
  margin-top: 3px;
  color: var(--status-caution);
}

.callout-body {
  min-width: 0;
  font-size: 1rem;
  line-height: 1.7;
  color: var(--text-secondary);
}

.callout-body strong {
  color: var(--text-highlight);
  font-weight: 600;
}

/* reset.css gives every anchor `color: inherit; text-decoration: none`, which
   inside a callout leaves a link indistinguishable from the sentence around
   it. Cyan alone is not enough here — the callout body is the one place the
   eye is already scanning for emphasis — so the underline carries it. */
.callout-body a {
  color: var(--accent-cyan);
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color var(--duration-fast) ease;
}

.callout-body a:hover {
  color: var(--text-highlight);
}

/* The same note inline inside a step sentence. */
.step-note {
  display: block;
  margin: var(--space-4) 0 0;
  padding-left: var(--space-4);
  border-left: 2px solid var(--border-glass);
  color: var(--text-secondary);
  font-size: 0.9375rem;
  font-weight: 400;
  line-height: 1.6;
}

/* --------------------------------------------------------------------------
   Troubleshooting
   The one page here you do not read start to finish. You arrive holding a
   symptom, so the four symptoms are listed first and the answers follow.
   -------------------------------------------------------------------------- */

/* The symptom index. Hairlines rather than cards: this is a list of four
   sentences, and boxing each one would be three borders too many. */
.qa-index {
  max-width: var(--container-narrow);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 var(--space-9);
}

.qa-index a {
  display: flex;
  align-items: baseline;
  gap: var(--space-4);
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--border-subtle);
  color: var(--text-secondary);
  font-size: 1rem;
  line-height: 1.5;
  transition: color var(--duration-fast) ease;
}

.qa-index a:hover {
  color: var(--text-highlight);
}

/* An odd count leaves the last symptom alone in the left column with a bare
   half-width hairline beside it. Let it take the full row instead, so the
   list ends on a rule that runs the whole way across. */
.qa-index a:last-child:nth-child(odd) {
  grid-column: 1 / -1;
}

.qa-index-num {
  flex-shrink: 0;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--accent-cyan);
}

.qa-index .icon {
  width: 16px;
  height: 16px;
  margin-left: auto;
  flex-shrink: 0;
  color: var(--text-tertiary);
  transition: transform var(--duration-fast) ease, color var(--duration-fast) ease;
}

.qa-index a:hover .icon {
  transform: translateX(3px);
  color: var(--accent-cyan);
}

/* A text-only answer. The procedure pages get their measure from the
   split-grid column; these have no media to sit beside, so they take it
   directly. */
.qa-answer {
  max-width: var(--measure-read);
  margin: 0 auto;
}

/* reset.css clears list markers globally. Here the numbers are the content —
   they are the order you try things in — so the list asks for them back. */
.trouble-steps {
  list-style: decimal outside;
  padding-left: var(--space-6);
  margin: 0;
  font-size: 1.0625rem;
  line-height: 1.75;
  color: var(--text-primary);
}

.trouble-steps li {
  display: list-item;
  margin-bottom: var(--space-5);
  padding-left: var(--space-2);
}

.trouble-steps li:last-child {
  margin-bottom: 0;
}

.trouble-steps li::marker {
  font-weight: 700;
  color: var(--accent-cyan);
}

.qa-answer .callout {
  margin: var(--space-8) 0 0;
}

/* A callout that closes a section rather than opening one. .callout's own
   `margin: 0 0 space-9` assumes it sits at the top of a section, above the
   thing it warns about; both of these trail the content instead and would
   otherwise touch the step directly above them. Same reasoning as
   `.split-grid + .split-grid` in core.css — a following block needs the
   breathing room a fresh section would have given it.

   The Q5 one also has to be re-centred: it is a sibling of the OS panels
   rather than a child of .qa-answer, so it never inherited that column's
   `margin: 0 auto` and sat flush left under centred text. */
.split-grid + .callout {
  margin-top: var(--space-11);
}

.os-content-wrapper + .callout {
  margin: var(--space-9) auto 0;
}

/* --------------------------------------------------------------------------
   OS tabs (manual/pairing/ #phone and manual/troubleshooting/ #q5 — Android / iOS)
   Dressed as the App Store / Google Play pair on app/: same .btn shape, same
   .btn-icon glyphs. Inactive tabs are .btn-secondary; the selected one takes
   .btn-primary's white fill, which is the strongest thing this system has and
   therefore the right way to say "this is the one you are reading".

   The panel is found by concatenating data-os with "-content" in
   /js/manual.js, so .android-content / .ios-content are a JS contract:
   renaming either side fails silently. data-i18n must stay on the inner
   <span> — updateLanguage() assigns innerHTML and would delete the logo.

   Each .os-tabs owns only the panels in the .os-content-wrapper directly after
   it, so the two groups on the sub-site do not toggle each other. That pairing
   of markup is also a contract: a wrapper that is not the tab list's next
   sibling is skipped entirely.
   -------------------------------------------------------------------------- */

.os-tabs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
  margin: 0 0 var(--space-10);
}

.os-tab-btn {
  font-family: inherit;
  cursor: pointer;
}

.os-tab-btn .btn-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.os-tab-btn.active {
  background: var(--text-primary);
  color: var(--bg-primary);
  border-color: transparent;
  box-shadow: var(--glow-soft);
}

.os-tab-btn.active:hover {
  background: var(--text-highlight);
  border-color: transparent;
}

.os-content {
  display: none;
  animation: fadeInUp 0.4s ease-out forwards;
}

.os-content.active {
  display: block;
}

/* --------------------------------------------------------------------------
   Hub (manual/index.html) — the guide's cover, not its index
   Modelled on Apple's support-guide welcome page: a tinted hero band with the
   title on the left and a product shot on the right, then the topics as
   alternating full-width rows, image and text trading sides down the page.

   Two departures from the reference, both deliberate. Apple's band is light
   grey on a white page; ours is --bg-surface on black, which is the same move
   (one step up the surface ladder) read through 제2원칙. And Apple's link blue
   becomes --accent-cyan, because a monochrome support page would be the one
   place on this site that abandons its own accent.

   This page carries no .manual-toc column. Neither does Apple's welcome page:
   on the cover you are choosing, and the whole body is already the choice. The
   sidebar returns on the topic pages, where you are reading and need to know
   where you are.
   -------------------------------------------------------------------------- */

.manual-hero {
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border-subtle);
}

.manual-hero-inner {
  max-width: var(--container-wide);
  margin: 0 auto;
  padding: var(--space-11) var(--space-6);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-10);
  align-items: center;
}

.manual-hero h1 {
  margin: 0 0 var(--space-3);
  font-size: clamp(2.25rem, 4vw, 3.25rem);
  font-weight: 700;
  line-height: 1.18;
  letter-spacing: -0.03em;
  color: var(--text-highlight);
}

.welcome-text {
  margin: 0;
  max-width: var(--measure-read);
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--text-secondary);
}

/* Contents disclosure. <details> rather than a script: the whole control is
   one native element with keyboard and screen-reader behaviour already
   correct, and this page loads no JS of its own. */
.manual-hero-toc {
  margin-top: var(--space-6);
}

.manual-hero-toc > summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  list-style: none;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--accent-cyan);
}

.manual-hero-toc > summary::-webkit-details-marker {
  display: none;
}

.manual-hero-toc > summary .icon {
  width: 18px;
  height: 18px;
  transition: transform var(--duration-base) var(--ease-apple);
}

.manual-hero-toc[open] > summary .icon {
  transform: rotate(45deg);
}

.manual-hero-toc-list {
  margin: var(--space-5) 0 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2) var(--space-6);
}

.manual-hero-toc-list a {
  display: block;
  padding: 2px 0;
  font-size: 0.9375rem;
  color: var(--text-secondary);
  transition: color var(--duration-fast) ease;
}

.manual-hero-toc-list a:hover {
  color: var(--text-highlight);
}

.manual-hero-media {
  margin: 0;
}

.manual-hero-media img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border-radius: var(--radius-lg);
}

/* --- Topic rows --------------------------------------------------------- */

.manual-rows {
  max-width: var(--container-wide);
  margin: 0 auto;
  padding: 0 var(--space-6) var(--space-12);
}

.manual-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-10);
  align-items: center;
  padding: var(--space-11) 0;
  border-top: 1px solid var(--border-subtle);
}

.manual-row:first-child {
  border-top: none;
}

/* Odd rows put the picture on the right. Source order stays text-then-image on
   every row, so the reading order is identical whichever side the picture is
   on — the zigzag is presentation only. */
.manual-row-alt .manual-row-media {
  order: -1;
}

/* One aspect ratio for every picture on the page, and object-fit to honour it
   whatever the source is. This is what makes the zigzag read as a rhythm: the
   first version let each image keep its own proportions, so a tall phone
   capture next to a wide product shot left the two columns meeting at
   different heights on every row and the whole column looked ragged. Cropping
   to a common frame costs a little of each photograph and buys a straight
   line down the page. */
.manual-row-media {
  margin: 0;
}

.manual-row-media img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border-radius: var(--radius-lg);
}

.manual-row h2 {
  margin: 0 0 var(--space-4);
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--text-highlight);
}

.manual-row p {
  margin: 0;
  max-width: var(--measure-read);
  font-size: 1.0625rem;
  line-height: 1.7;
  color: var(--text-secondary);
}

.manual-row-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: var(--space-5);
  font-size: 1rem;
  font-weight: 600;
  color: var(--accent-cyan);
  transition: gap var(--duration-fast) ease;
}

.manual-row-link:hover {
  gap: 10px;
}

.manual-row-link .icon {
  width: 16px;
  height: 16px;
}

/* --------------------------------------------------------------------------
   Responsive — 1024 / 768 / 640, per design.md
   The detail pages inherit core.css's breakpoints with the rest of the shared
   vocabulary; only the cover's own furniture needs anything here.
   -------------------------------------------------------------------------- */

@media (max-width: 768px) {
  .qa-index {
    grid-template-columns: 1fr;
    gap: 0;
  }

  /* Cover: the zigzag collapses. Alternating sides only means something when
     there are two columns to alternate. */
  .manual-hero-inner {
    grid-template-columns: 1fr;
    gap: var(--space-8);
    padding: var(--space-9) var(--space-4);
  }

  .manual-hero-toc-list {
    grid-template-columns: 1fr;
  }

  .manual-rows {
    padding: 0 var(--space-4) var(--space-11);
  }

  .manual-row {
    grid-template-columns: 1fr;
    gap: var(--space-7);
    padding: var(--space-9) 0;
  }

  .manual-row-alt .manual-row-media {
    order: 0;
  }

  .os-tabs {
    max-width: none;
  }
}

@media (max-width: 1024px) {
  /* Below the split-grid breakpoint every row is one column, so alternating
     sides means nothing and the media would otherwise lead. */
  .split-grid-alt > .card-media-shot {
    order: 0;
  }

  .card-media-shot {
    padding: var(--space-5);
  }
}

@media (max-width: 640px) {
  .card-media-shot > img {
    max-height: 340px;
  }
}
