/* ==========================================================================
   Base — reset, typography, layout primitives
   ========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: var(--font-stack);
  font-size: var(--font-size);
  line-height: var(--line-height);
  color: var(--text);
  background-color: var(--surface);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* The Korean font stack, tracking and leading moved to korean.css, which is
   linked only on /kr/ pages so English readers do not download a Korean
   webfont. What stays here is line BREAKING, which is cheap and must not
   depend on that file having loaded. */

/* Korean has no spaces inside a word, so the default break-anywhere behaviour
   splits words mid-syllable. keep-all forces breaks at spaces instead. */
html[lang="ko"] h1,
html[lang="ko"] h2,
html[lang="ko"] h3,
html[lang="ko"] h4,
html[lang="ko"] p,
html[lang="ko"] li,
/* A FAQ question is a sentence set in an element this list would otherwise
   miss. <summary> is not a heading and not a paragraph, so without naming it
   here the questions are the only Korean sentences on the site that break
   mid-word. */
html[lang="ko"] summary,
/* Not a <p>, but a two-line block of Korean on a phone — the same rule
   applies, and it is the narrowest text on the site. Covers both placements
   of the band: the strip under the header and the in-page block. */
html[lang="ko"] .banner__body {
  word-break: keep-all;
}

/* keep-all holds Korean words together but still breaks at spaces and at a
   middle dot (·), either of which would split the accent across two lines and
   strand half the gradient. This guards the accent phrase whatever it happens
   to be — it has been a name pair, a single token and a two-word phrase over
   successive drafts, and the guard should not have to be removed and restored
   each time. It does mean the accent must stay short: it cannot wrap, so a
   long one would overflow a narrow phone. */
html[lang="ko"] .hero__title mark {
  white-space: nowrap;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  margin: 0 0 0.5em;
  font-weight: 700;
  line-height: 1.25;
  color: var(--heading);
  text-wrap: balance;
}

h1 { font-size: var(--h1); }
h2 { font-size: var(--h2); }
h3 { font-size: var(--h3); }
h4 { font-size: var(--h4); }

p {
  margin: 0 0 var(--content-gap);
  text-wrap: pretty;
}

p:last-child {
  margin-bottom: 0;
}

a {
  color: var(--color-1);
  text-decoration: none;
  /* Legacy root.css sets `p, li, a { font-size: 1.125rem }`, which made links
     inside a paragraph a different size from the text around them. A link
     should always take the size of its context. */
  font-size: inherit;
}

a:hover {
  color: var(--primary);
}

img,
picture,
svg,
video {
  max-width: 100%;
  height: auto;
  display: block;
}

ul,
ol {
  margin: 0;
  padding: 0;
}

strong {
  font-weight: 700;
  color: var(--color-4);
}

:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 3px;
  border-radius: 4px;
}

::selection {
  background-color: var(--primary);
  color: #fff;
}

/* --- Layout primitives ---------------------------------------------------
   .container    standard content width
   .container--narrow  prose width, used for centred section intros
   ------------------------------------------------------------------------ */

.container {
  width: var(--container-edge);
  max-width: var(--container-max);
  margin-inline: auto;
}

.container--narrow {
  max-width: var(--container-narrow);
}

/* The site header is fixed, so every page offsets its content by the header
   height once, here — rather than each first-section component doing its own.
   --header-h is the header's measured height (published by nav.js); the token
   is only a first-paint fallback. Using the token alone left a 7px strip of
   page background showing above the hero, because it guessed 63px against a
   header that is actually 56px. */
main {
  padding-top: var(--header-h, var(--header-height));
}

/* A page whose header carries a notice is taller than the token alone
   describes, and for the frame before nav.js publishes the measurement the
   fallback is all there is — without this the top of the page starts under
   the strip. --header-h still wins the moment it exists. */
body.has-notice main {
  padding-top: var(--header-h, calc(var(--header-height) + var(--notice-height)));
}

/* Vertical rhythm between top-level sections. */
.section {
  margin-block: var(--section-gap);
}

.section--flush-top {
  margin-top: 0;
}

/* Pairs with .section--flush-top on the block below it. For two sections that
   are one idea — the contact panel and its map — the full --section-gap reads
   as a semantic break they do not have, and the map floats off on its own. */
.section--to-map {
  margin-bottom: 20px;
}

/* The first section on a page. The full section gap exists to separate
   sections from each other — against the header it just wastes the fold. */
.section--lead {
  margin-top: 28px;
}

@media only screen and (min-width: 62.5em) {
  .section--lead {
    margin-top: 40px;
  }
}

/* Skip link — visible only on keyboard focus. */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 999;
  padding: 1rem 1.5rem;
  background: var(--primary);
  color: #fff;
  font-weight: 700;
}

.skip:focus {
  left: 0;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
