/* =========================================================================
   KoreaBeautyHealth.com — "farm" theme

   Built on the section patterns of the client's chosen reference template:

     hero          copy on plain ground, photograph filling the right half to
                   the top edge, a card lifted over its foot
     stat banner   photograph dimmed to near-black, heading and figures over it
     ruled heading centred between a green rule and an orange one
     icon row      dark discs holding a single glyph
     product block narrow column of solid cards beside a row of picture cards
     timeline      alternating cards either side of a centre line
     closing panel a wide photograph butted against a solid colour panel
     footer        link columns, then a dark bar for the copyright alone

   Its palette and type, sampled from the template itself:
     orange #F69946   green #81BD50   near-black #232323   cream #F9F4EE
     Livvic for display, Lato for text.

   Livvic and Lato carry no Hangul, so a Korean face is named after each one.
   Browsers choose per character, which is what lets a Latin-only display face
   set the English words and figures while Hangul falls through to Noto Sans KR.

   The previous design is kept whole in site-simple.css; switch with THEME in
   config.php.

   Order: tokens, reset, type, shared pieces, then one block per section in
   the order the page renders them.
   ========================================================================= */

/* ---------------------------------------------------------------- tokens */
:root {
  --orange:      #f69946;
  --orange-dark: #e8823a;
  --orange-soft: #fdefe1;
  --green:       #81bd50;
  --green-dark:  #6ea944;

  --dark:        #232323;
  --dark-2:      #2e2e2e;
  --cream:       #f9f4ee;
  --white:       #ffffff;

  --ink:         #232323;
  --ink-2:       #75736d;
  --ink-3:       #9a978f;
  --border:      #e8e1d8;

  --display: "Livvic", "Noto Sans KR", "Malgun Gothic", -apple-system,
             BlinkMacSystemFont, "Segoe UI", sans-serif;
  --sans:    "Lato", "Noto Sans KR", "Malgun Gothic", -apple-system,
             BlinkMacSystemFont, "Segoe UI", sans-serif;

  --wrap: 1180px;
  --gap: clamp(20px, 4vw, 44px);
  --section-y: clamp(28px, 3.25vw, 50px);
  --radius: 0px;          /* the template squares off every corner */
}

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

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

body {
  margin: 0;
  background: var(--white);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 24px;
  line-height: 1.85;
  -webkit-font-smoothing: antialiased;
  /* Korean wraps between words, never mid-word. The headings have said this
     since the first build; body copy did not, which is why a Korean sentence
     could leave a stray syllable stranded on its own line. Harmless to Latin
     text, where not breaking a word is the default anyway. */
  word-break: keep-all;
}

img { max-width: 100%; height: auto; display: block; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; }

[id] { scroll-margin-top: 92px; }

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--dark);
  color: #fff;
  padding: 12px 20px;
}
.skip-link:focus { left: 0; }

:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }

/* ------------------------------------------------------------ typography */
h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 700;
  line-height: 1.18;
  letter-spacing: -0.015em;
  margin: 0;
  word-break: keep-all;   /* Korean wraps between words, never mid-word */
}

h1 { font-size: clamp(22.8px, 3.24vw, 40.8px); }
h2 { font-size: clamp(27px, 3.2vw, 42px); }
h3 { font-size: clamp(27px, 2.4vw, 34.5px); line-height: 1.35; }
h4 { font-size: 25.5px; line-height: 1.4; }

p { margin: 0; }

.lede {
  color: var(--ink-2);
  font-size: clamp(22.5px, 1.65vw, 24.75px);
  max-width: 72ch;
  margin-top: 22px;
}
.lede--center { margin-inline: auto; text-align: center; }

.prose { max-width: 24ch; }
h2.prose { max-width: 19ch; }

.eyebrow {
  font-family: var(--sans);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--orange);
  margin: 0 0 20px;
  /* Inline flow rather than a flex row: at the enlarged size these labels wrap
     in narrow columns and on phones, and a flex row cannot wrap mid-phrase
     without stranding the brackets on the first line. */
  display: block;
}
.eyebrow .bk { color: currentColor; opacity: .45; }
.eyebrow .bk:first-child { margin-right: 8px; }
.eyebrow .bk:last-child  { margin-left: 8px; }

/* .cap captions the charts and keeps the enlarged size; .src is the small
   credit under each statistic and was asked to come back down. */
.src { font-size: 13.5px; }

.cap {
  font-size: 17.25px;
  letter-spacing: 0.02em;
  color: var(--ink-3);
  line-height: 1.65;
}

/**
 * The template's signature heading: centred, with a green rule running out to
 * the left and an orange one to the right.
 */
.ruled {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: clamp(18px, 3vw, 40px);
  text-align: center;
  max-width: none;
}
.ruled::before, .ruled::after { content: ""; height: 2px; }
/* A heading that carries a link holds its words in a span, so the grid still
   sees exactly three children: rule, words, rule. */
.ruled > span { display: block; }
.ruled::before { background: var(--green); }
.ruled::after  { background: var(--orange); }

/* -------------------------------------------------------------- skeleton */
.wrap {
  width: min(100% - 2 * var(--gap), var(--wrap));
  margin-inline: auto;
}
.wrap--narrow { width: min(100% - 2 * var(--gap), 800px); }

.section { position: relative; padding-block: var(--section-y); }
.section--serve,
.section--benefits { background: var(--cream); }

.subsection { margin-top: clamp(28px, 3.5vw, 50px); }

/* -------------------------------------------------------------- buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 15px 32px;
  border: 2px solid transparent;
  border-radius: var(--radius);
  font-family: var(--sans);
  font-size: 19.5px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  transition: background-color .18s ease, border-color .18s ease, color .18s ease;
}
.btn-sm { padding: 11px 22px; font-size: 17.25px; }

.btn-primary { background: var(--orange); color: #fff; }
.btn-primary:hover { background: var(--orange-dark); }

.btn-ghost { border-color: var(--border); color: var(--ink); }
.btn-ghost:hover { border-color: var(--orange); color: var(--orange); }

.btn-solid { background: var(--white); color: var(--dark); }
.btn-solid:hover { background: var(--cream); }

.btn-ondark { border-color: rgba(255, 255, 255, .5); color: #fff; }
.btn-ondark:hover { border-color: #fff; background: rgba(255, 255, 255, .12); }

.link-more {
  display: inline-block;
  margin-top: 18px;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  border-bottom: 2px solid var(--orange);
  padding-bottom: 3px;
}

/* --------------------------------------------------------------- header */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--white);
  border-bottom: 1px solid var(--border);
}
.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 84px;
}

/* The page's type went up 50% at the client's request; the header did not, so
   its button keeps the size the nav bar was laid out around. */
.site-header .btn { font-size: 13px; }

.brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  text-decoration: none;
  font-family: var(--display);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.02em;
  white-space: nowrap;
}
.mark {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--orange);
  color: #fff;
  font-family: var(--sans);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.nav-panel {
  display: flex;
  align-items: center;
  gap: 30px;
  flex: 1;
  justify-content: flex-end;
}
.navlinks { display: flex; gap: 28px; }
.navlinks a {
  text-decoration: none;
  white-space: nowrap;   /* a label must never break mid-word */
  font-size: 13.5px;
  font-weight: 700;
  color: var(--ink-2);
  padding-block: 8px;
  border-bottom: 2px solid transparent;
  transition: color .16s ease, border-color .16s ease;
}
.navlinks a:hover,
.navlinks a.is-current { color: var(--ink); border-bottom-color: var(--orange); }

.navcta { display: flex; align-items: center; gap: 18px; }

.langtoggle {
  display: inline-flex;
  border: 1px solid var(--border);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
}
.langtoggle a, .langtoggle span {
  padding: 6px 13px;
  white-space: nowrap;
  text-decoration: none;
  color: var(--ink-3);
}
.langtoggle .active { background: var(--dark); color: #fff; }
.langtoggle a:hover { color: var(--orange); }


/* The language switch is generated per page, so it points at *this* page in
   the other language rather than always at the home page. It arrives as a
   <ul class="langswitch">; making that the flex row keeps the list a real
   list -- display:contents would have folded it into the toggle, at the cost
   of dropping the list from the accessibility tree in older browsers. */
.langtoggle .langswitch { display: flex; margin: 0; padding: 0; list-style: none; }
/* the <li> has to stretch, or the current language's dark block stops short
   of the toggle's border and leaves a hairline of ground above and below */
.langtoggle .lang-item { display: flex; }
.langtoggle .lang-item.is-current span { background: var(--dark); color: #fff; }

/* The header button never wraps — the row collapses to a menu instead. Content
   buttons elsewhere must stay free to wrap: "Schedule an Introductory Call"
   does not fit on one line on a phone. */
.site-header .btn { padding: 10px 20px; white-space: nowrap; }

.nav-toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  cursor: pointer;
}
.nav-toggle span { display: block; width: 22px; height: 2px; background: var(--ink); }

/* ----------------------------------------------------------------- hero */
.hero { padding-block: 0; }

.hero-grid {
  width: 100%;
  max-width: none;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  min-height: min(78vh, 720px);
}
.hero-copy {
  /* Left gutter lines the copy up with every other section's wrap; the right
     side only needs breathing room before the photograph. */
  /* Pulled up into the white space above: the eyebrow sat too low, and the
     headline and the photograph have to share the first screen. */
  padding: clamp(18px, 2.4vw, 34px) clamp(32px, 4vw, 64px)
           clamp(32px, 4vw, 56px) max(var(--gap), calc((100vw - var(--wrap)) / 2));
}
/* Wider measures: at the reduced headline size the old ones left most of the
   column empty. 21ch fills it and costs the headline a line. */
.hero-copy h1 { max-width: 21ch; }
.hero-copy .lede { max-width: 52ch; }

.hero-figure { position: relative; align-self: stretch; min-height: 380px; }
/* Anchored to the very top of the frame. The 22% offset that used to sit here
   was tuned for the old photograph; the 2026-09-10 image carries the GoKorea
   Beauty lockup baked into its top-right corner, and any vertical offset clips
   the TM and the ring at narrow widths. */
.hero-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
            object-position: 50% 0%; }

/* The GoKorea Beauty mark used to be a .hero-badge overlay here. The client
   supplied a hero image with the lockup baked in (2026-09-10), so the
   overlay and its rules were removed rather than doubling the logo. */

.hero-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 36px; }

.trustline {
  margin-top: 30px;
  font-size: 16.5px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
  max-width: 44ch;
}

/* The card lifted over the foot of the hero photograph. */
.hero-cardwrap {
  position: relative;
  z-index: 2;
  display: flex;
  justify-content: flex-end;
  margin-top: clamp(-140px, -9vw, -70px);
  pointer-events: none;
}
.hero-card {
  pointer-events: auto;
  width: min(100%, 660px);
  background: var(--white);
  box-shadow: 0 22px 60px rgba(35, 35, 35, .13);
  padding: clamp(20px, 2.4vw, 30px);
}
.bridge-svg { width: 100%; height: auto; }

.bnode-title { font-family: var(--display); font-size: 13px; font-weight: 700; fill: var(--ink); letter-spacing: .06em; text-transform: uppercase; }
.bnode-label { font-family: var(--sans); font-size: 11px; fill: var(--ink-3); }
.bnode-chip  { font-family: var(--sans); font-size: 12px; fill: var(--ink-2); }
.bnode-box   { fill: var(--cream); stroke: var(--border); }
.bnode-hub   { fill: var(--orange); }
.bhub-title  { font-family: var(--display); font-size: 12px; font-weight: 700; fill: #fff; letter-spacing: .08em; }
.bhub-sub    { font-family: var(--sans); font-size: 10.5px; fill: #fff; }
.bridge-line { stroke: #d8d0c6; }
.bdot        { fill: var(--green); }

/* -------------------------------------------------- the opportunity: band */
.section--opportunity { padding-top: clamp(26px, 3vw, 44px); }
/* Half the gap on either side of these two joins, as marked up. */
.section--opportunity { padding-bottom: calc(var(--section-y) / 2); }
.section--difference  { padding-top: calc(var(--section-y) / 2); }
.section--serve       { padding-bottom: calc(var(--section-y) / 2); }
.section--benefits    { padding-top: calc(var(--section-y) / 2); }

.statband {
  position: relative;
  background: var(--dark);
  padding-block: clamp(32px, 4vw, 54px);
  /* halved with the section rhythm: this is a seam between the band and
     the charts under it, not the band's own breathing room */
  margin-bottom: clamp(28px, 3.5vw, 48px);
  overflow: hidden;
}
.statband-media { position: absolute; inset: 0; }
.statband-media .band-img { width: 100%; height: 100%; object-fit: cover; }
/* The photograph is atmosphere, not information — dimmed until the type
   sitting on it is comfortably legible. */
.statband-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(28, 28, 28, .82);
}
.statband-inner { position: relative; z-index: 1; text-align: center; }
/* Wide enough for this heading to break once rather than twice. */
/* Same reasoning as the lead blocks above: at 34ch this heading left
   "있습니다." stranded on its own line. */
.statband h2 {
  color: #fff;
  max-width: none;
  margin-inline: auto;
  text-wrap: balance;
}
.statband .lede {
  color: rgba(255, 255, 255, .74);
  margin-inline: auto;
  text-align: center;
  text-wrap: balance;
}
/* The heading and lede are centred on the band, but the label above them
   sits where every other section puts it: hard against the left edge. */
.statband .eyebrow { text-align: left; }

.tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(24px, 4vw, 56px);
  margin-top: clamp(22px, 2.5vw, 34px);
}
.tile { text-align: center; padding-top: 26px; position: relative; }
.tile::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 46px;
  height: 2px;
  background: var(--orange);
}
.num {
  font-family: var(--display);
  font-size: clamp(38px, 4.6vw, 58px);
  font-weight: 700;
  line-height: 1.1;
  color: #fff;
}
.num .unit { color: var(--orange); }
.tile-text {
  margin: 14px auto 12px;
  font-size: 21px;
  color: rgba(255, 255, 255, .72);
  max-width: 30ch;
  /* keep-all first: Korean must break between words, never inside one --
     balancing without it split 최대 and 단일 down the middle. */
  word-break: keep-all;
  text-wrap: balance;
}
.tile .src { color: rgba(255, 255, 255, .42); letter-spacing: .1em; text-transform: uppercase; }

/* -------------------------------------------------------------- charts */
.chart-row {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 26px;
}
.chart-card {
  margin: 0;
  background: var(--white);
  border: 1px solid var(--border);
  padding: clamp(24px, 2.6vw, 36px);
}
.section--opportunity .wrap > .chart-card { margin-top: clamp(18px, 2vw, 28px); }
.chart-title { font-size: 28.5px; }
.chart-card .cap { margin-top: 8px; }
.chart-src { margin-top: 20px; }

.bar-group {
  display: flex;
  align-items: flex-end;
  gap: 4%;
  height: 235px;
  margin-top: 34px;
  padding-bottom: 46px;
  position: relative;
}
.bar-col {
  flex: 1;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  position: relative;
}
.bar-col.has-gap { margin-right: 5%; }

.bar { position: relative; min-height: 4px; transition: filter .18s ease; }
.bar--accent { background: var(--green); }
.bar--gold   { background: var(--orange); }
.bar--muted  { background: #ddd6cc; }
.bar:hover   { filter: brightness(1.06); }

.bar .val {
  position: absolute;
  top: -26px;
  left: 0;
  right: 0;
  text-align: center;
  font-family: var(--display);
  font-size: 19.5px;
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
}
.bar-label {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  padding-top: 12px;
  text-align: center;
  font-size: 17.25px;
  line-height: 1.5;
  color: var(--ink-3);
}

/* Hover note, built from the data-tip attribute so no script is needed. */
.bar[data-tip]:hover::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 28px);
  left: 50%;
  transform: translateX(-50%);
  /* Was nowrap at the body size, which turned the longest note into a strip
     376px wide over a 154px bar -- wider than the card holding it, so it hung
     off the edge. Smaller type, and wrapping inside a set width, keeps a note
     over the bar it belongs to. */
  width: max-content;
  max-width: 150px;
  white-space: normal;
  word-break: keep-all;   /* Korean wraps between words, never mid-word */
  text-align: center;
  line-height: 1.4;
  background: var(--dark);
  color: #fff;
  font-size: 12.75px;
  padding: 6px 9px;
  pointer-events: none;
  z-index: 5;
}
/* An end column centred on its own bar would still reach past the side of
   the card, so the outermost two hang from their bar rather than centre on
   it. Nothing in between needs it: there is a bar either side to give way. */
.bar-col:first-child .bar[data-tip]:hover::after {
  left: 0;
  transform: none;
}
.bar-col:last-child .bar[data-tip]:hover::after {
  left: auto;
  right: 0;
  transform: none;
}

.grp-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  margin-top: 20px;
  font-size: 17.25px;
  color: var(--ink-3);
}
.legend-item { display: inline-flex; align-items: center; gap: 8px; }
.swatch { width: 11px; height: 11px; display: inline-block; }
.swatch--accent { background: var(--green); }
.swatch--muted  { background: #ddd6cc; }

/* ------------------------------------------------------------ barriers */
.barriers { background: var(--cream); padding-block: clamp(28px, 3.5vw, 48px); margin-top: clamp(28px, 3.5vw, 48px); }
.barriers h3 { font-size: clamp(24px, 2.8vw, 36px); }

.barrier-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: clamp(16px, 2vw, 28px);
  margin-top: clamp(20px, 2.5vw, 30px);
}
.barrier { text-align: center; }
/* The template puts each glyph in a dark disc; the glyphs here are letters
   rather than icons, which suits the same treatment. */
.bicon {
  display: grid;
  place-items: center;
  width: 62px;
  height: 62px;
  margin: 0 auto 18px;
  border-radius: 50%;
  background: var(--dark);
  color: var(--orange);
  font-family: var(--display);
  font-size: 24px;
  line-height: 1;
}
.barrier h4 { margin-bottom: 8px; }
.barrier p { font-size: 20.25px; color: var(--ink-2); line-height: 1.7; }

/* --------------------------------------------------- centred lead blocks */
/* Two sections open with a heading and a paragraph that the client asked to
   fill the column and sit centred rather than hug the left edge. Only the
   paragraph that follows the heading is caught here -- a section may close
   with another .lede, and those are centred one at a time by adding
   lede--center in the page, which is what the audience section's closing
   paragraph now does. */
.section--difference > .wrap > h2,
.section--audience   > .wrap > h2 {
  /* The column, not a narrower measure. At 30ch these headings dropped their
     last two or three words onto a line of their own -- "you." alone in
     English, "이유입니다." alone in Korean -- which is what the client kept
     marking up. balance then evens the remaining lines so a short last line
     cannot come back at another window width. */
  max-width: none;
  margin-inline: auto;
  text-align: center;
  text-wrap: balance;
}
.section--difference > .wrap > h2 + .lede,
.section--audience   > .wrap > h2 + .lede {
  max-width: none;
  text-wrap: balance;
  margin-inline: auto;
  text-align: center;
}

/* ---------------------------------------------------------- comparison */
.section--difference .lede { max-width: 68ch; }
.compare {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 26px;
  margin-top: clamp(20px, 2.5vw, 32px);
}
.compare-col { padding: clamp(26px, 3vw, 40px); border: 1px solid var(--border); }
.compare-col.is-gkb { background: var(--dark); border-color: var(--dark); }

.compare-head {
  font-size: 30px;
  padding-bottom: 20px;
  border-bottom: 2px solid var(--border);
  margin-bottom: 6px;
}
.is-gkb .compare-head { color: #fff; border-bottom-color: rgba(255, 255, 255, .18); }

.crow {
  display: flex;
  gap: 15px;
  padding: 16px 0;
  border-bottom: 1px solid var(--border);
  font-size: 21px;
  color: var(--ink-2);
}
.is-gkb .crow { border-bottom-color: rgba(255, 255, 255, .12); color: rgba(255, 255, 255, .76); }
.crow:last-child { border-bottom: 0; }
.mk { color: var(--ink-3); flex: none; font-weight: 700; }
.is-gkb .mk { color: var(--green); }

/* --------------------------------------------------------- who we serve */
.serve-layout {
  display: grid;
  grid-template-columns: minmax(0, 260px) minmax(0, 1fr);
  gap: clamp(22px, 2.4vw, 30px);
  /* stretch, not start: the orange figure is asked to run down to the same
     baseline as the cards beside it. */
  align-items: stretch;
}
.serve-aside {
  display: grid;
  grid-template-rows: auto 1fr;
  gap: clamp(22px, 2.4vw, 30px);
}

.serve-titlecard {
  background: var(--dark);
  color: #fff;
  padding: clamp(26px, 2.6vw, 34px);
}
.serve-titlecard h2 { color: #fff; font-size: clamp(23px, 2vw, 28px); }
.serve-titlecard .link-more { color: #fff; }

/* The one figure worth repeating outside the banner, in the template's solid
   colour card. */
.serve-figure { background: var(--orange); color: #fff; padding: clamp(26px, 2.6vw, 34px); }
.serve-figure__num {
  display: block;
  font-family: var(--display);
  font-size: 44px;
  font-weight: 700;
  line-height: 1.1;
}
.serve-figure__num .unit { opacity: .7; }
.serve-figure__text { display: block; margin-top: 12px; font-size: 20.25px; line-height: 1.7; }

.serve-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(18px, 2vw, 26px); }
.serve-card { background: var(--white); display: flex; flex-direction: column; }
.serve-media { aspect-ratio: 4 / 3; overflow: hidden; }
.serve-img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s ease; }
.serve-card:hover .serve-img { transform: scale(1.04); }
.serve-body { padding: clamp(20px, 2vw, 26px); }
.tag {
  font-size: 16.5px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--orange);
  margin-bottom: 12px;
}
.serve-body h3 { margin-bottom: 14px; }
.serve-body p { font-size: 21px; color: var(--ink-2); }

/* ------------------------------------------------------------ benefits */
.feature-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  column-gap: clamp(32px, 5vw, 80px);
  margin-top: clamp(20px, 2.5vw, 30px);
}
.feature-list li {
  position: relative;
  padding: 15px 0 15px 34px;
  font-size: 21.75px;
  color: var(--ink-2);
  border-bottom: 1px solid var(--border);
}
.feature-list li::before {
  content: "›";
  position: absolute;
  left: 4px;
  top: 13px;
  color: var(--orange);
  font-size: 28.5px;
  font-weight: 700;
  line-height: 1.4;
}

.funnel-wrap {
  margin-top: clamp(22px, 2.5vw, 32px);
  background: var(--white);
  border: 1px solid var(--border);
  padding: clamp(24px, 3vw, 44px);
  overflow-x: auto;
}
.funnel-svg { width: 100%; min-width: 640px; height: auto; }
.ftxt text { font-family: var(--sans); font-size: 12.5px; font-weight: 700; fill: var(--ink-2); }
.funnel-line { stroke: #ded7cd; }
.funnel-dot circle { fill: var(--orange); }
.funnel-target { fill: var(--dark); }
.funnel-target-title { font-family: var(--display); font-size: 15px; font-weight: 700; fill: #fff; }
.funnel-target-sub { font-family: var(--sans); font-size: 11.5px; fill: rgba(255, 255, 255, .72); }

/* ------------------------------------------------------------ audience */
/* The template's history timeline: a centre line, ringed markers, and cards
   alternating either side of it. Four steps read as a sequence here, which is
   exactly what the copy describes. */
.audience-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 480px);
  gap: clamp(32px, 4vw, 64px);
  align-items: start;
  /* Tighter top and bottom: the photograph is asked to come up to meet the
     lead block, and the closing paragraph to sit nearer the steps -- while
     still staying clear of them. */
  margin: clamp(18px, 2vw, 28px) 0 clamp(16px, 1.8vw, 24px);
}
.process { position: relative; }
.process::before {
  content: "";
  position: absolute;
  left: 30px;
  top: 8px;
  bottom: 8px;
  width: 2px;
  background: var(--border);
}
.pstep { position: relative; padding: 0 0 30px 76px; }
.pstep:last-child { padding-bottom: 0; }
.pn {
  position: absolute;
  left: 16px;
  top: 0;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--orange);
  color: #fff;
  font-family: var(--display);
  font-size: 19.5px;
  font-weight: 700;
}
.pstep h3 { font-size: 25.5px; margin-bottom: 8px; }
.pstep p { font-size: 20.25px; color: var(--ink-2); }

.audience-media { margin: 0; overflow: hidden; }
/* Square, not the portrait 3/4 it was: the source is a selfie, and the
   outstretched arm only survives a crop this wide. */
.audience-img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; }

.quote-block {
  /* Wider than it was and centred, but deliberately short of the full page. */
  margin: clamp(36px, 4vw, 56px) auto 0;
  background: var(--cream);
  border-left: 4px solid var(--orange);
  padding: clamp(28px, 3vw, 44px);
  max-width: min(96ch, 90%);
}
.quote-block p {
  font-size: clamp(22.5px, 1.88vw, 27px);
  line-height: 1.9;
  color: var(--ink);
}

/* ------------------------------------------------- the real competitor */
/* Sits in the tight seam between the charts and "why we are different", so
   it carries the same halved padding as the two sections it joins. */
.section--competition { padding-block: calc(var(--section-y) / 2); }

/* The client's mockup drew this as a rounded card in a serif face; built
   here out of the theme's own parts instead -- squared corners, cream
   ground, the green rule the mission card already uses. */
.rival-card {
  background: var(--cream);
  border-left: 4px solid var(--green);
  padding: clamp(28px, 3vw, 44px);
}
.rival-head { font-size: clamp(25.5px, 2.2vw, 31.5px); }
/* Heading, figure and paragraph centred on the card. The badges and the
   source line under them are left as they are: they read as a row of
   labels and a credit, not as part of the statement above. */
.rival-head,
.rival-stat,
.rival-body { text-align: center; }
/* .rival-body is width-limited, so centring its text is not enough -- the
   block itself has to sit in the middle too. */
.rival-body { margin-inline: auto; }

/* The figure is the point of the block, so it is set in the display face at
   heading weight and in orange, like every other number on the page. */
.rival-stat {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(22.5px, 2vw, 28.5px);
  line-height: 1.35;
  color: var(--orange);
  margin-top: 16px;
  word-break: keep-all;
}
.rival-stat .arrow { padding-inline: 4px; }

.rival-body {
  margin-top: 18px;
  color: var(--ink-2);
  font-size: clamp(21px, 1.5vw, 22.5px);
  max-width: 78ch;
}

/* Squared and bordered like .vbadge, which is the page's established way of
   showing a row of short facts. */
.rival-list { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 28px; }
.rbadge {
  border: 1px solid var(--border);
  background: var(--white);
  padding: 9px 18px;
  font-size: 17.25px;
  line-height: 1.5;
  color: var(--ink);
  font-weight: 700;
}
.rbadge-note { color: var(--ink-2); font-weight: 400; }

.rival-src { margin-top: 22px; }

/* ------------------------------------------------------------- vetting */
.vetting-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(32px, 4vw, 72px);
  /* The label above this grid is the section's, not the copy column's, so the
     copy starts where the label left off -- level with the top of the photo. */
  align-items: start;
}
.vetting-media { margin: 0; order: -1; overflow: hidden; }
.vetting-img { width: 100%; aspect-ratio: 7 / 5; object-fit: cover; }

.vet-badges { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 32px; }
.vbadge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--border);
  padding: 10px 20px;
  font-size: 19.5px;
  font-weight: 700;
  color: var(--ink-2);
}
.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--green); }

/* ------------------------------------------------------------- pricing */
.price-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 26px;
  margin-top: clamp(22px, 2.5vw, 32px);
  align-items: stretch;
}
.price-card {
  position: relative;
  background: var(--white);
  border: 1px solid var(--border);
  padding: clamp(28px, 2.8vw, 40px);

  /* Reserve a band at the top for the "Most Popular" tab, which is positioned
     absolutely into the corner and so shares a line with the heading. Under
     about 1090px the tab's left edge crossed into the word and "Featured" read
     as "Featurea". Horizontal room is not the answer: at 320px the card is
     ~264px wide inside its padding while the word and the tab need ~285px, and
     "Featured" is one word so it cannot wrap out of the way. Separating them
     vertically is what holds at every width.

     Set on every card rather than only .feat -- padding just the tabbed card
     would clear the tab but drop its heading below the other two headings at
     every width, trading a narrow-screen bug for an everywhere misalignment. */
  padding-top: 48px;

  display: flex;
  flex-direction: column;
}
.price-card.feat { background: var(--dark); border-color: var(--dark); color: #fff; }
.price-card.feat h3 { color: #fff; }

.pill {
  position: absolute;
  top: 0;
  right: 0;
  background: var(--orange);
  color: #fff;
  font-size: 15.75px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 7px 14px;
}
.pdesc { font-size: 20.25px; color: var(--ink-2); margin-top: 10px; }
.feat .pdesc { color: rgba(255, 255, 255, .68); }

.rate {
  font-family: var(--display);
  font-size: 34.5px;
  font-weight: 700;
  color: var(--orange);
  margin: 24px 0 20px;
  padding-bottom: 24px;
  border-bottom: 1px solid var(--border);
}
.feat .rate { border-bottom-color: rgba(255, 255, 255, .18); }

.price-features { flex: 1; margin-bottom: 30px; }
.price-features li {
  position: relative;
  padding: 9px 0 9px 22px;
  font-size: 20.25px;
  color: var(--ink-2);
}
.feat .price-features li { color: rgba(255, 255, 255, .74); }
.price-features li::before {
  content: "›";
  position: absolute;
  left: 2px;
  color: var(--orange);
  font-weight: 700;
}
.price-card .btn { width: 100%; }
.feat .btn-primary { background: var(--orange); }

/* --------------------------------------------------------------- about */
.about-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: clamp(32px, 4vw, 64px);
  align-items: start;
  margin-top: clamp(18px, 2vw, 26px);
}
/* The round KBH mark that used to sit here was removed at the client's
   request, which is what leaves the text flush with the column edge. */
.founder { display: block; }
.founder .prose { max-width: 62ch; }
.founder p { font-size: 21.75px; color: var(--ink-2); }
.founder p + p { margin-top: 18px; }
.about-media { margin: 0; overflow: hidden; }
.about-img { width: 100%; aspect-ratio: 7 / 5; object-fit: cover; }

.mission-card {
  /* Box and text both centred. */
  margin: clamp(36px, 4vw, 56px) auto 0;
  background: var(--cream);
  border-left: 4px solid var(--green);
  padding: clamp(28px, 3vw, 40px);
  max-width: min(84ch, 90%);
  text-align: center;
}
.mission-card p { font-size: 22.5px; color: var(--ink-2); line-height: 1.9; }
.mission-card .mission-title {
  font-family: var(--display);
  font-weight: 700;
  color: var(--ink);
  margin-bottom: 10px;
}

/* ----------------------------------------------------------------- faq */
.faq { margin-top: clamp(20px, 2vw, 28px); max-width: 880px; margin-inline: auto; }
.faq details { border-bottom: 1px solid var(--border); }
.faq details:first-child { border-top: 1px solid var(--border); }
.faq summary {
  list-style: none;
  cursor: pointer;
  padding: 26px 46px 26px 0;
  position: relative;
  font-family: var(--display);
  font-weight: 700;
  font-size: 25.5px;
  line-height: 1.45;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--orange);
  font-size: 33px;
  font-weight: 700;
}
.faq details[open] summary::after { content: "–"; }
.faq .a { padding: 0 46px 28px 0; font-size: 21.75px; color: var(--ink-2); }

/* ------------------------------------------------------- closing panel */
.cta-final { padding-block: 0 var(--section-y); }
.cta-layout {
  display: grid;
  /* An even split, photograph against panel. The panel used to take the
     larger share so "Schedule an Introductory Call" could hold one line;
     .cta-panel .btn below is what buys that back at the narrower width. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: stretch;
}
.cta-media { margin: 0; overflow: hidden; }
/* 30% down, not the middle: where this box is wide and short -- tablet and
   phone -- a centred band cuts the faces off. */
.cta-img { width: 100%; height: 100%; min-height: 340px; object-fit: cover;
           object-position: 50% 30%; }

.cta-panel {
  background: var(--green);
  color: #fff;
  padding: clamp(36px, 4.5vw, 68px);
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.cta-panel .eyebrow { color: #fff; opacity: .8; }

.cta-panel .contact-value { display: flex; align-items: center; gap: 10px; }
.contact-icon { width: clamp(20px, 2.2vw, 26px); height: auto; flex: none; }
/* tel: and mailto: make these usable on a phone; they inherit so the panel
   looks exactly like the client's mockup. */
.cta-panel .contact-value a { color: inherit; text-decoration: none; }
.cta-panel .contact-value a:hover,
.cta-panel .contact-value a:focus-visible { text-decoration: underline; }

/* The panel signs off with two marks -- GoKorea Beauty on the left, the Korean
   American Association on the right -- pushed to the two ends of the hairline
   rule, as the client's 2026-09-10 mockup shows. Widths are the mockup's own
   proportions measured against the rule (47.7% and 42.2%), so both marks scale
   with the panel and keep their aspect ratio. White knockout, not colour: brand
   red on #81bd50 clashes, and a white card on the green reads as stuck on. */
.cta-brand {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: clamp(22px, 2.6vw, 30px);
  padding-top: clamp(24px, 3vw, 40px);
  border-top: 1px solid rgba(255, 255, 255, .32);
}
.cta-brand img { display: block; height: auto; min-width: 0; }
.cta-brand img:first-child { width: 47.5%; }
.cta-brand img:last-child  { width: 42%; }

.cta-panel h2 { color: #fff; max-width: 16ch; }
.cta-panel .lede { color: rgba(255, 255, 255, .88); max-width: 19.5em; }
/* 19.5em is the mockup's measure: at the lede's 23px it gives ~450px, which
   breaks the Korean after 페이지를 exactly as the client drew it. */
/* Spacing per the client's 2026-09-10 mockup: the button sits closer to the
   intro and the contact block a little further from the button. */
.cta-panel .hero-actions { margin-top: 23px; }

/* Kept on one line at the enlarged size: a little less tracking and a little
   less padding buy the room, and the label is not allowed to break. It is
   released again below 560px, where the panel is genuinely too narrow. */
.cta-panel .btn {
  white-space: nowrap;
  letter-spacing: .07em;
  padding-inline: 26px;
}
/* Set at the same size as the paragraph above it, so the address reads as
   part of the panel rather than as small print. A label and an address
   rather than a second button: there is nothing to click here, and styling
   it as a link would promise there was. */
.contact-details {
  margin-top: 33px;
  font-size: clamp(22.5px, 1.65vw, 24.75px);
  color: rgba(255, 255, 255, .88);
}
.contact-label { font-weight: 700; color: #fff; letter-spacing: .01em; }
.contact-value { margin-top: 6px; letter-spacing: .01em; line-height: 1.45; }

/* ------------------------------------------------------------ contact form */
/* Fields sit two to a row on a wide screen and one to a row on a narrow one.
   field--wide spans both, which is what keeps an email address and an address
   from being squeezed into half a column. */
.contact-form-wrap { margin-top: clamp(40px, 5vw, 72px); }
.contact-form-wrap .form-intro { max-width: 52ch; margin-bottom: clamp(28px, 3vw, 40px); }

.contact-form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* Row gap cut to 62.5% of what it was -- every term scaled by the same
     factor, so the rows tighten by the same 37.5% at any width. The
     column gap is untouched: the two are doing different jobs. */
  gap: clamp(11.25px, 1.25vw, 16.25px) clamp(20px, 3vw, 40px);
  max-width: 900px;
  margin-inline: auto;
}
.field { display: flex; flex-direction: column; gap: 8px; }
.field--wide { grid-column: 1 / -1; }

.contact-form label {
  font-family: var(--sans);
  font-size: 17.25px;
  font-weight: 700;
  color: var(--ink-2);
}
.contact-form .req { color: var(--orange); }

.contact-form input,
.contact-form textarea {
  font-family: var(--sans);
  font-size: 19.5px;
  color: var(--ink);
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 13px 16px;
  width: 100%;
}
.contact-form textarea { resize: vertical; min-height: 96px; }
.contact-form input:focus,
.contact-form textarea:focus {
  outline: none;
  border-color: var(--orange);
  box-shadow: 0 0 0 3px var(--orange-soft);
}
/* :user-invalid, not :invalid -- a required field is invalid the moment the
   page loads, and marking all seven red before a word is typed is hostile.
   :user-invalid waits until the field has actually been used. */
.contact-form input:user-invalid,
.contact-form textarea:user-invalid { border-color: #c8624e; }

.form-foot {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 6px;
}
.form-required { margin: 0; font-size: 17.25px; color: var(--ink-3); }

/* The honeypot. Off screen rather than display:none, because a bot that
   skips hidden fields is a bot this would not have caught anyway. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-note {
  grid-column: 1 / -1;
  margin: 0;
  padding: 12px 16px;
  background: var(--orange-soft);
  color: var(--ink-2);
  font-size: 17.25px;
}
/* The same box, when the news is bad. */
.form-note--bad { background: #fbe6e0; color: #86271d; }

@media (max-width: 640px) {
  .contact-form { grid-template-columns: minmax(0, 1fr); }
  .form-foot { flex-direction: column; align-items: stretch; }
  .form-foot .btn { width: 100%; }
}

/* --------------------------------------------------------------- footer */
.site-footer { background: var(--white); }
.foot-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, .7fr) minmax(0, 1.5fr);
  gap: clamp(28px, 4vw, 64px);
  padding-block: clamp(24px, 3vw, 40px);
}
.foot-tag { margin: 18px 0 24px; font-size: 20.25px; color: var(--ink-2); max-width: 34ch; }

.foot-head {
  font-size: 17.25px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
  margin-bottom: 18px;
}
.foot-nav li { padding: 5px 0; }
.foot-nav a {
  position: relative;
  padding-left: 18px;
  font-size: 20.25px;
  color: var(--ink-2);
  text-decoration: none;
}
.foot-nav a::before { content: "›"; position: absolute; left: 0; color: var(--orange); font-weight: 700; }
.foot-nav a:hover { color: var(--orange); }

.sources ol { list-style: decimal; padding-left: 20px; }
.sources li { font-size: 17.25px; line-height: 1.9; color: var(--ink-3); }

.foot-bottom { background: var(--dark); padding-block: 22px; }
.foot-bottom p { font-size: 12.5px; color: rgba(255, 255, 255, .6); text-align: center; }
/* The medical disclaimer the client added on 2026-09-10. Centred like the
   copyright above it -- that rule already existed -- but held to a readable
   measure, because centred text set across the full page width is hard to
   track back to the start of each line. */
.foot-legal { max-width: 86ch; margin-inline: auto; margin-bottom: 10px; line-height: 1.65; }

/* ----------------------------------------------------------------- 404 */
.notfound { display: grid; place-items: center; min-height: 78vh; text-align: center; }
.notfound .eyebrow { justify-content: center; }
.notfound .lede { margin-inline: auto; }
.notfound .hero-actions { justify-content: center; }

/* ------------------------------------------------------------ narrower */
@media (max-width: 1080px) {
  .serve-layout { grid-template-columns: 1fr; }
  .serve-aside { grid-template-columns: repeat(2, 1fr); }
  .serve-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 1000px) {
  .hero-grid { grid-template-columns: minmax(0, 1fr); min-height: 0; }
  .hero-copy { padding-inline: var(--gap); }
  /* Taller than it was: the hero photograph is portrait, and a shallow band
     crops it down to a head. */
  .hero-figure { min-height: 420px; order: -1; }
  .hero-cardwrap { margin-top: -60px; justify-content: center; }

  /* minmax(0,...) not 1fr: a bare 1fr keeps min-width:auto, and a wide
     photograph then pushes the column past the edge of the screen. */
  .chart-row,
  .compare,
  .vetting-grid,
  .about-grid,
  .audience-grid,
  .cta-layout { grid-template-columns: minmax(0, 1fr); }

  .serve-grid,
  .price-grid { grid-template-columns: 1fr; }
  .barrier-grid { grid-template-columns: repeat(3, 1fr); }
  .tiles { grid-template-columns: 1fr; }
  .foot-grid { grid-template-columns: 1fr; }
  .audience-img { aspect-ratio: 16 / 9; }
  .cta-img { min-height: 260px; }
}


/**
 * Collapse the nav well before it runs out of room.
 *
 * The labels are short words in Korean and longer ones in English, and both
 * sit beside a language switch and a button. Measured, the row needs about
 * 1100px in Korean and 1200px in English before items start breaking mid-word.
 * One breakpoint has to serve both languages, so it is set past the wider of
 * the two rather than at the point the narrower one happens to survive.
 */
/* Stacking a little earlier than the rest of the page: between here and
   1000px the panel is too narrow for its own button. */
@media (max-width: 1150px) {
  .cta-layout { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 560px) {
  .cta-panel .btn { white-space: normal; }
  /* The inset is worth having on a wide screen and only wastes room here. */
  .mission-card, .quote-block { max-width: 100%; }
}

@media (max-width: 1200px) {
  .nav-toggle { display: flex; }
  .nav-panel {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 20px;
    background: var(--white);
    border-bottom: 1px solid var(--border);
    padding: 24px var(--gap) 30px;
  }
  .nav-panel.is-open { display: flex; }
  .navlinks { flex-direction: column; gap: 2px; }
  .navlinks a { display: block; padding: 11px 0; font-size: 15px; }
  .navcta { justify-content: space-between; }
}

@media (max-width: 820px) {
  .feature-list { grid-template-columns: 1fr; }
  .ruled { grid-template-columns: 1fr; }
  .ruled::before, .ruled::after { display: none; }
}

@media (max-width: 560px) {
  .barrier-grid,
  .serve-aside { grid-template-columns: 1fr; }
  .bar-group { height: 195px; }
  .btn { width: 100%; }
  .hero-actions .btn { width: auto; flex: 1 1 auto; }
}


/* Very narrow phones. "KoreaBeautyHealth.com" is a long wordmark set solid,
   and at this width it pushes the menu button off the screen — so the brand
   steps down rather than the layout breaking. */
@media (max-width: 400px) {
  :root { --gap: 16px; }
  .nav { gap: 12px; }
  .brand { font-size: 15px; gap: 8px; }
  .mark { width: 25px; height: 25px; font-size: 8px; }
}

/* A reader who has asked for less movement gets none. */

/* ------------------------------------------------- how the bridge works */
/* One drawing in place of two: the bridge that sat in the hero card and the
   funnel that sat under the benefits list. They told one story between them
   and neither carried it alone.

   The ground is cream, like .section--serve and .section--benefits; the
   eyebrow, the ruled heading and the lede are the site's own components, used
   unchanged. Everything else is confined to this section, so the generic
   names below -- card, hub, badge -- cannot reach another page. */
.section--how {
  background: var(--cream);
  /* The eyebrow that opened this section was removed; the space it occupied
     goes with it. */
  padding-top: calc(var(--section-y) / 2);
}

.section--how .board { display: block; width: 100%; height: auto; }
.section--how .board.tall { display: none; }
@media (max-width: 860px) {
  .section--how .board.wide { display: none; }
  .section--how .board.tall { display: block; }
}

/* type inside the drawing */
.section--how .t-zone    { font-family: var(--display); font-weight: 700; font-size: 25px; letter-spacing: .12em; fill: var(--ink); }
.section--how .t-sub     { font-family: var(--sans); font-size: 20.25px; fill: var(--ink-2); }
.section--how .t-chan    { font-family: var(--sans); font-size: 19.5px; fill: var(--ink); }
.section--how a { text-decoration: none; }
.section--how .t-hub     { font-family: var(--display); font-weight: 700; font-size: 26px; letter-spacing: .06em; fill: var(--white); }
/* At the enlarged size this label filled the hub edge to edge; the tracking
   is what gives it back its margins, rather than shrinking the type. */
.section--how .t-hubsub  { font-family: var(--sans); font-weight: 700; font-size: 13px; letter-spacing: .04em; fill: var(--ink); }
/* 17.25px was sized to sit under a 26px wordmark. Under the lockup it read
   louder than the brand name it captions, so it steps down. */
.section--how .t-badge   { font-family: var(--sans); font-weight: 700; font-size: 19.5px; fill: var(--ink); }
.section--how .t-flow    { font-family: var(--sans); font-weight: 700; font-size: 15.75px; letter-spacing: .16em; text-transform: uppercase; fill: var(--ink-3); }
.section--how .t-land    { font-family: var(--display); font-weight: 600; font-size: 22.5px; fill: var(--ink); }
.section--how .t-landsub { font-family: var(--sans); font-size: 18px; fill: var(--ink-2); }
.section--how .t-disc    { font-family: var(--sans); font-weight: 700; font-size: 20.25px; letter-spacing: .06em; fill: var(--white); }

/* shapes, in the card language the rest of the page already uses */
.section--how .card     { fill: var(--white); stroke: var(--border); stroke-width: 1; }
.section--how .chan     { fill: var(--white); stroke: var(--border); stroke-width: 1; }
.section--how .disc     { fill: var(--dark); }          /* .bicon, carrying a numeral */
.section--how .hub      { fill: #fff; stroke: var(--orange); stroke-width: 2; }
/* Node 02 is a white card like 01 and 03 now that it carries the GoKorea
   Beauty lockup; the orange survives as this edge and as the pulsing
   .hubring, which is what buys back the emphasis the solid fill gave. */
.section--how .hubring  { fill: none; stroke: var(--orange); opacity: .45; stroke-width: 2; }
.section--how .badge    { fill: none; stroke-width: 1.5; }   /* .vbadge, as a box */
.section--how .badge-g  { stroke: var(--green); }
.section--how .badge-o  { stroke: var(--orange); }
.section--how .mark-g   { fill: var(--green); }
/* The 01/03 badge dot moved from a <circle> into a <tspan> so the dot and
   its label centre together -- SVG cannot centre a circle against text
   without measuring the text, and the label differs per language. */
.section--how .mark-g-t { fill: var(--green); font-size: .62em; }
.section--how .mark-o-t { fill: var(--orange); font-size: .62em; }
.section--how .mark-o   { fill: var(--orange); }
.section--how .flowline { fill: none; stroke-width: 2; stroke-linecap: round; }
.section--how .flow-g   { stroke: var(--green); }
.section--how .flow-o   { stroke: var(--orange); }
.section--how .spoke,
.section--how .stem     { fill: none; stroke: #a89e90; stroke-width: 2.2; stroke-dasharray: 3 6; stroke-linecap: round; }
.section--how .dot-g    { fill: var(--green); }
.section--how .dot-o    { fill: var(--orange); }

/* ---- the reveal --------------------------------------------------------
   Nothing moves until the section is on screen; site.js adds s1..s5 in turn.
   Every animated element states its own finished position, so the graphic
   renders complete when the classes never arrive -- which is what happens
   with JavaScript off, and what the reduced-motion block below forces. */
.section--how.anim [data-rise]  { opacity: 0; transform: translateY(16px); }
.section--how.anim [data-left]  { opacity: 0; transform: translateX(-26px); }
.section--how.anim [data-right] { opacity: 0; transform: translateX(26px); }
.section--how.anim [data-pop]   { opacity: 0; transform: scale(.84); transform-origin: center; transform-box: fill-box; }
.section--how.anim [data-rise],
.section--how.anim [data-left],
.section--how.anim [data-right],
.section--how.anim [data-pop] {
  transition: opacity .6s cubic-bezier(.22, .8, .28, 1), transform .6s cubic-bezier(.22, .8, .28, 1);
}
.section--how.anim.s1 [data-stage="1"],
.section--how.anim.s2 [data-stage="1"], .section--how.anim.s2 [data-stage="2"],
.section--how.anim.s3 [data-stage="1"], .section--how.anim.s3 [data-stage="2"], .section--how.anim.s3 [data-stage="3"],
.section--how.anim.s4 [data-stage="1"], .section--how.anim.s4 [data-stage="2"], .section--how.anim.s4 [data-stage="3"], .section--how.anim.s4 [data-stage="4"],
.section--how.anim.s5 [data-stage="1"], .section--how.anim.s5 [data-stage="2"], .section--how.anim.s5 [data-stage="3"],
.section--how.anim.s5 [data-stage="4"], .section--how.anim.s5 [data-stage="5"] { opacity: 1; transform: none; }

.section--how.anim .flowline { stroke-dasharray: 220; stroke-dashoffset: 220; }
.section--how.anim.s2 .flow-g, .section--how.anim.s3 .flow-g,
.section--how.anim.s4 .flow-g, .section--how.anim.s5 .flow-g,
.section--how.anim.s4 .flow-o, .section--how.anim.s5 .flow-o {
  stroke-dashoffset: 0; transition: stroke-dashoffset .85s ease-out;
}

/* the travelling dots are SMIL, as the old bridge's were; the stage classes
   only decide when they become visible */
.section--how .runner { opacity: 0; transition: opacity .5s ease; }
.section--how.anim.s3 .run-g, .section--how.anim.s4 .run-g,
.section--how.anim.s5 .run-g, .section--how.anim.s5 .run-o { opacity: 1; }

.section--how .hubring { transform-origin: center; transform-box: fill-box; }
.section--how.anim.s3 .hubring,
.section--how.anim.s4 .hubring,
.section--how.anim.s5 .hubring { animation: how-pulse 3.2s ease-out infinite; }
@keyframes how-pulse {
  0%        { transform: scale(.94); opacity: .45; }
  70%, 100% { transform: scale(1.5); opacity: 0; }
}


/* The market section opens with a dark band but carries its own top padding,
   which is transparent. That is invisible when a white section sits above it,
   and a white stripe when a coloured one does -- so where "how it works"
   comes first, the band butts straight against the cream. The band's own
   padding is what holds the heading off its top edge. */
.section--how + .section--opportunity { padding-top: 0; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .bdot { display: none; }
  .section--how.anim [data-rise],
  .section--how.anim [data-left],
  .section--how.anim [data-right],
  .section--how.anim [data-pop] { opacity: 1; transform: none; transition: none; }
  .section--how.anim .flowline { stroke-dashoffset: 0; }
  .section--how .runner { opacity: 1; }
  .section--how .hubring { animation: none !important; opacity: .45; }
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

@media print {
  .site-header, .nav-toggle, .statband-media, .hero-figure { display: none; }
  body { background: #fff; }
  .section { padding-block: 24px; }
}
