@charset "utf-8";

/* ============================================================
   DAY1 / DEPLOYMENT AGE
   Magazine editorial recruitment page — stylesheet
   Self-hosted type only. No external runtime requests.

   Responsive model: one system, not four skins.
   - type and spacing are fluid (clamp) so 390 -> 440 is continuous
   - two recomposition tiers: <=900px (single column) and <=640px
     (portrait phone: cover, folio bar, filter rail, stacked JD tables)
   - safe-area insets feed the page gutters and every sticky/fixed edge
   ============================================================ */

/* --- 1. Type ------------------------------------------------ */

/* `block` held every word off the screen until 624KB of variable font had
   arrived — on a slow phone, seconds of a blank page carrying the whole site's
   first impression. The document is worth more than the face it is set in, so
   it is drawn in the fallback and re-set when SUIT lands. The template preloads
   the file so that window is as short as the connection allows, which is what
   the ADC site has always done. */
@font-face {
  font-family: "SUIT Variable";
  src: url("assets/fonts/SUIT-Variable.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* --- 2. Tokens ---------------------------------------------- */

/* ------------------------------------------------------------
   Colour is expressed as one print-plate set, never as literal
   hues, so the one palette moves surfaces, text, rules,
   controls, focus rings and interactive states together.

     --paper / --paper-deep   the two reading surfaces
     --ink / --ink-soft       primary and secondary text on paper
     --accent   (plate 1)     structural ink: links, folio numerals,
                              pressed filters, progress, focus on paper
     --mark     (plate 2)     highlight ink: bullets, cover numeral,
                              underlines, focus on dark plates
     --ink-*                  the reverse plate (contents + colophon)
     --*-on                   the text colour that prints on that plate
     --focus / --focus-a/b/ink     focus ring per surface

   Every pair below is measured by checks/verify.py in every
   palette: 4.5:1 for text, 3:1 for control borders and rings.
   ------------------------------------------------------------ */

:root {
  /* ---- Oxidized Copper — the site's palette ------------------
     Verdigris on a cool mineral paper with a bleached ochre
     mark. Locked in: this is a published site, not a palette
     comparison. */
  --paper: #eaeee9;
  --paper-deep: #d8e0d7;
  --ink: #101613;
  --ink-soft: #3b4642;

  --accent: #0f5f52;
  --accent-deep: #0a463c;
  --accent-on: #f2f7f1;
  --mark: #edcf9a;
  --mark-deep: #dbb87f;
  --mark-on: #101613;

  /* the reverse plate: contents spread and colophon */
  --ink-flat: #101613;
  --ink-plate: #18211d;
  --ink-plate-2: #050807;
  --ink-on: #eaeee9;
  --ink-accent: #edcf9a;
  --ink-sub: #a9b3ad;

  --focus: #0f5f52;
  --focus-a: #edcf9a;
  --focus-b: #0f5f52;
  --focus-ink: #edcf9a;

  --field-bg: #f7faf6;
  --field-ink: #101613;
  --field-hint: #56605b;

  /* Solid, not translucent: control boundaries have to hold 3:1
     against the paper they sit on rather than against whatever
     happens to be behind them. */
  --rule-strong: #848884;    /* 3.06:1 on paper */
  /* The cover numeral prints under every cover label, so it carries
     its own ink: it must hold 4.5:1 against --ink, --ink-soft and
     --accent, which all overprint it on a phone. */
  --crop-ink: var(--mark);
  --rail-shadow: rgba(16, 22, 19, 0.6);

  /* ---- derived from the set above --------------------------- */
  --rule: color-mix(in srgb, var(--ink) 18%, transparent);
  --field-rule: var(--rule-strong);
  --ink-rule: color-mix(in srgb, var(--ink-on) 28%, transparent);
  --ink-rule-soft: color-mix(in srgb, var(--ink-on) 18%, transparent);
  --ink-rule-strong: color-mix(in srgb, var(--ink-on) 46%, transparent);

  --sans: "SUIT Variable", system-ui, -apple-system, "Apple SD Gothic Neo",
          "Malgun Gothic", "Noto Sans KR", sans-serif;

  /* ---- reading type ------------------------------------------
     Hangul sets on a square em, so every reading decision here is
     stated in the unit a Korean reader actually counts: one em is
     one syllable block.

     Size is fluid with no step at any breakpoint:
     17.57px at 390 -> 17.71px at 440 -> 18px from 543px up, and
     never below the 16px phone floor.

     Leading is coupled to measure. A 22-syllable phone column
     returns the eye sooner than a 37-syllable desktop column, so it
     is set one notch tighter and spends the saving on glyph size
     instead of on white space between lines.

     Tracking is the small negative that SUIT wants at reading size;
     its syllable blocks sit a touch open between 17 and 19px. */
  --fs-body: clamp(1.09375rem, 1.03rem + 0.28vw, 1.125rem);
  --lh-body: 1.7;           /* document default — controls, furniture */
  --lh-read: 1.78;          /* running Korean prose */
  --lh-read-list: 1.68;     /* enumerated items and JD table cells */
  --ls-read: -0.012em;
  /* Latin all-caps kickers and functional readouts, 12px -> 13px.
     Hangul labels never take this tracking; see the tracking ladder
     under section 2b. */
  --fs-meta: clamp(0.75rem, 0.7rem + 0.11vw, 0.8125rem);
  /* Smallest type allowed to carry canonical source text on a phone. */
  --fs-source-min: 1rem;    /* 16px */

  /* Measure in syllables, not in rem: a column that changes size then
     keeps its glyph count instead of keeping its pixel width. */
  --measure: 37em;          /* the running reading column */
  --measure-tight: 30em;    /* the narrow feature's centred column */
  --measure-wide: 42em;     /* the wide feature's authored column */

  /* The floor is the phone margin, and it is load-bearing: below 400px the
     4vw ramp is under it, so every portrait phone reads at exactly the floor.
     At 1.25rem the 402px column ran 21.3 syllables, under the 22 a Korean
     column wants; 1rem is the conventional phone margin and buys the 22nd
     syllable back without crowding the screen edge. The ramp above 400px is
     untouched, so nothing wider than a phone moves. */
  --gutter: clamp(1rem, 4vw, 4.5rem);
  /* Page gutters absorb the landscape notch; env() is 0 without it. */
  --pad-l: max(var(--gutter), env(safe-area-inset-left));
  --pad-r: max(var(--gutter), env(safe-area-inset-right));
  /* app.js measures the live folio bar and the sticky filter rail. */
  --bar-h: 3.5rem;
  --rolebar-offset: 0px;
  --page: 84rem;

  --plate-bg: var(--paper);
  --plate-ink: var(--ink);
  --plate-rule: var(--rule);
  --plate-accent: var(--accent);
}

/* --- 2b. Tracking ladder ------------------------------------
   One rule decides letter-spacing everywhere on this page, because
   the two scripts it sets want opposite things:

   - Latin all-caps kickers (THE INVITATION, CONTENTS, OPEN ROLES)
     are drawn from separable letterforms and read better opened up:
     0.14em to 0.26em, the larger values on the shortest labels.
   - Hangul is drawn as composed syllable blocks. Opening those up
     pulls the blocks apart before it separates the words, so any
     label carrying Hangul stays at or below 0.06em, and running
     Korean prose takes the small negative --ls-read.
   - Display Hangul takes an optical ladder: the larger it is set,
     the tighter it tracks (-0.03em on a phone, -0.05em on a cover).

   Micro-labels that are Latin-only keep --fs-meta and its tracking.
   Micro-labels that carry Hangul keep the size and drop the tracking.
   ------------------------------------------------------------ */

/* --- 3. Reset ----------------------------------------------- */

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

html {
  overflow-x: clip;
  scroll-behavior: smooth;
  /* app.js measures the live sticky chrome and overwrites this. */
  scroll-padding-top: var(--sticky-offset, 5.5rem);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  overflow-x: clip;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  word-break: keep-all;
  overflow-wrap: anywhere;
  text-rendering: optimizeLegibility;
}

img, svg { max-width: 100%; }

p { margin: 0 0 1.15em; }
ul { margin: 0 0 1.3em; padding: 0; list-style: none; }
h1, h2, h3 { margin: 0; font-weight: 800; line-height: 1.24; letter-spacing: -0.018em; }
strong { font-weight: 700; }
em { font-style: normal; }

a { color: inherit; }
/* One ring token, resolved per surface. Every plate re-declares
   --focus below, so the ring stays visible on every plate
   instead of relying on a single global accent. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: 1px;
}

::selection { background: var(--mark); color: var(--mark-on); }

/* Theme switching is a token swap, never an animation. This one
   frame of suppression makes it instantaneous under any motion
   preference, including prefers-reduced-motion: no-preference. */
/* --- 4. Skip links ------------------------------------------ */

.skiplinks { margin: 0; padding: 0; list-style: none; }
.skiplinks a {
  position: fixed;      /* reachable from any scroll position */
  left: -9999px;
  top: 0;
  z-index: 90;
  display: block;
  min-width: 44px;
  min-height: 44px;
  padding: 0.7rem 1.1rem;
  background: var(--ink);
  color: var(--paper);
  font-size: 0.9375rem;
  font-weight: 700;
  text-decoration: none;
}
.skiplinks a:focus {
  left: calc(0.75rem + env(safe-area-inset-left));
  top: calc(0.75rem + env(safe-area-inset-top));
}
html:not(.js) .skip--js { display: none; }

/* --- 5. Folio bar (running head + reading progress) --------- */

.folio-bar {
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--paper);
  border-bottom: 1px solid var(--rule);
  /* The bar meets the notch / Dynamic Island under viewport-fit=cover. */
  padding-top: env(safe-area-inset-top);
}
.folio-bar__in {
  max-width: var(--page);
  margin: 0 auto;
  padding-left: var(--pad-l);
  padding-right: var(--pad-r);
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: 3.25rem;
}
/* The masthead: the mark, a rule, and the organisation's name set small and
   opened up. It carries the full name at every width — this is a new
   organisation, and the bar is the one place a reader meets the name on every
   page. The name sets on two lines so it costs the bar height it already has
   rather than width a phone does not. */
/* One masthead, wherever it is set: the mark, a rule, and the organisation's
   name on two lines. The bar and the colophon differ only in how large they
   set it, which is the one value --mark-h carries — so the name can never come
   out stacked in one place and strung out in the other. */
.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
}
.wordmark__ident {
  padding-left: 0.6rem;
  border-left: 1px solid currentColor;
  font-size: 0.5625rem;      /* 9px — a mark's legend, not reading matter */
  font-weight: 800;
  letter-spacing: 0.12em;
  line-height: 1.32;
  opacity: 0.66;
}

.folio-bar__flag {
  flex: none;
  min-width: 44px;
  min-height: 44px;
  padding: 0.4rem 0;
  white-space: nowrap;
  --mark-h: 1.15rem;
}
/* The company's own DAY1 lettering rather than a typeset approximation of it.
   It is carried as an alpha mask and painted with currentColor, so the letters
   are the corporate ones while the ink stays this site's. The text stays in the
   DOM, and without mask support it is what prints — a solid block is a worse
   answer than the words. */
.folio-bar__flag .brandmark {
  font-size: 1rem;
  font-weight: 900;
  letter-spacing: -0.04em;
}
@supports (mask: url("assets/brand/day1-wordmark.png")) or
          (-webkit-mask: url("assets/brand/day1-wordmark.png")) {
  .brandmark {
    /* One height decides the mark; the width follows the artwork's own
       109 x 59, so the lettering can never be set out of proportion. */
    display: block;
    height: var(--mark-h);
    width: calc(var(--mark-h) * 109 / 59);
    background-color: currentColor;
    font-size: 0;
    -webkit-mask: url("assets/brand/day1-wordmark.png") no-repeat left center / contain;
    mask: url("assets/brand/day1-wordmark.png") no-repeat left center / contain;
  }
}
.folio-bar__run {
  margin: 0 auto 0 0;
  display: flex;
  align-items: center;
  gap: 0.55rem;
  min-width: 0;
  font-size: var(--fs-meta);
  font-weight: 600;
  color: var(--ink-soft);
}
.folio-bar__num {
  font-weight: 800;
  color: var(--accent);
  letter-spacing: 0.1em;
}
.folio-bar__rule {
  width: 1.75rem;
  height: 1px;
  background: var(--rule-strong);
}
/* The running head prints the article's own Korean title, so it takes
   the Hangul side of the ladder, and its width is stated in syllables. */
.folio-bar__title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 22em;
  letter-spacing: 0.004em;
}
/* Right-aligned on its own, not by leaning on the running head's auto margin:
   the running head is hidden below 900px, and without this the nav used to
   bunch against the masthead in the 641-900px band. */
.folio-bar__nav {
  display: flex;
  gap: 0.15rem;
  flex: none;
  margin-left: auto;
}
.folio-bar__nav a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;          /* every nav action is a full touch target */
  min-height: 44px;
  padding: 0 0.7rem;
  /* Korean nav labels; the bar's 3.25rem floor absorbs the extra px. */
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0.004em;
  text-decoration: none;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
}
.folio-bar__nav a:hover { border-bottom-color: var(--accent); }
/* The page the reader is already on is named, not offered. The action is
   excluded by name: it is painted, and this rule would put its ink and its
   ground at the same value — 1.42:1, which is what it did. */
.folio-bar__nav a:not(.folio-bar__act)[aria-current="page"] {
  border-bottom-color: var(--accent);
  color: var(--accent);
}
/* Applying is the one action the site exists for, so it prints as an action
   rather than as another destination. */
.folio-bar__act {
  margin-left: 0.3rem;
  background: var(--accent);
  color: var(--accent-on);
}
.folio-bar__act:hover { background: var(--accent-deep); border-bottom-color: transparent; }
.folio-bar__act[aria-current="page"] {
  background: var(--accent-deep);
  color: var(--accent-on);
  border-bottom-color: transparent;
}
.folio-bar__progress {
  height: 3px;
  background: var(--paper-deep);
}
.folio-bar__progress i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--accent);
}

/* --- 6. Issue shell ----------------------------------------- */

.issue { display: block; }

.verbatim-source { display: block; }

/* Once composed, the only source blocks still sitting directly under the
   article are the ones the score does not print — the end-of-document
   sentinel, and the paragraph whose contents were lifted into the
   application spread. They stay in the DOM; they just stop printing. */
html.issue-built .verbatim-source > .source-block,
html.issue-built .source-consumed__text { display: none; }

/* Bleed section frame shared by every editorial state */
.spread {
  position: relative;
  padding: clamp(3.5rem, 7vw, 7rem) var(--pad-r) clamp(3.5rem, 7vw, 7rem) var(--pad-l);
  background: var(--plate-bg);
  color: var(--plate-ink);
  overflow: clip;
  scroll-margin-top: calc(var(--bar-offset, 4rem) + 1rem);
}
.spread__in {
  max-width: var(--page);
  margin: 0 auto;
  position: relative;
}

/* Colour plates. Each one carries its own ink, rule and focus ring
   so it stays legible on every plate it prints over. */
.plate--paper { --plate-bg: var(--paper); }
.plate--paper-deep { --plate-bg: var(--paper-deep); }
.plate--accent {
  --plate-bg: linear-gradient(172deg, var(--accent) 0%, var(--accent-deep) 100%);
  --plate-ink: var(--accent-on);
  --plate-rule: color-mix(in srgb, var(--accent-on) 34%, transparent);
  --plate-accent: var(--mark);
  --focus: var(--focus-a);
}
.plate--ink {
  --plate-bg: linear-gradient(172deg, var(--ink-plate) 0%, var(--ink-plate-2) 100%);
  --plate-ink: var(--ink-on);
  --plate-rule: var(--ink-rule);
  --plate-accent: var(--ink-accent);
  --focus: var(--focus-ink);
}
.plate--mark {
  --plate-bg: linear-gradient(172deg, var(--mark) 0%, var(--mark-deep) 100%);
  --plate-ink: var(--mark-on);
  --plate-rule: color-mix(in srgb, var(--mark-on) 34%, transparent);
  --plate-accent: var(--accent);
  --focus: var(--focus-b);
}

/* Registration marks: printer's furniture, CSS only */
.regmark {
  position: absolute;
  width: 26px;
  height: 26px;
  pointer-events: none;
  opacity: 0.9;
}
.regmark::before,
.regmark::after {
  content: "";
  position: absolute;
  background: var(--plate-rule);
}
.regmark::before { left: 50%; top: 0; width: 1px; height: 100%; }
.regmark::after { top: 50%; left: 0; height: 1px; width: 100%; }
.regmark--tl { left: var(--pad-l); top: 1.4rem; }
.regmark--tr { right: var(--pad-r); top: 1.4rem; }

/* Cropped display type used as image: the chapter numbers on three of the
   spreads, and the industry's two letters on the cover. It is set as one line
   whatever it holds — at cover size two characters are wider than a phone, and
   without this the pair broke across two lines and printed as two separate
   marks stacked up the page. */
.cropnum {
  position: absolute;
  white-space: nowrap;
  font-weight: 900;
  line-height: 0.72;
  letter-spacing: -0.06em;
  pointer-events: none;
  user-select: none;
}

/* --- 7. Cover ----------------------------------------------- */

.cover {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding-top: clamp(2rem, 5vw, 4rem);
  /* Clears the home indicator when the cover bleeds to the screen edge. */
  padding-bottom: max(clamp(2rem, 5vw, 3.5rem), calc(env(safe-area-inset-bottom) + 1.25rem));
  --plate-bg: var(--paper);
}
.cover__glyph {
  right: -0.09em;
  bottom: -0.24em;
  font-size: clamp(20rem, 46vw, 46rem);
  color: var(--crop-ink);
  z-index: 0;
}
.cover__in {
  position: relative;
  z-index: 1;
  max-width: var(--page);
  width: 100%;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: clamp(2rem, 6vh, 4.5rem);
  flex: 1;
}
/* The cover's kicker and the rule under it. The mark and the name are not
   repeated here: the folio bar sits directly above this line and carries both
   at every scroll position, so printing them again a centimetre lower was the
   same two words twice on one screen. What stays is what only the cover
   says — which call this is. */
.cover__flag {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
  border-bottom: 3px solid var(--ink);
  padding-bottom: 0.7rem;
}
.cover__issue {
  font-size: clamp(0.7rem, 1.1vw, 0.8125rem);
  font-weight: 700;
  color: var(--accent);
  letter-spacing: 0.22em;
}
/* The measure is stated in syllables rather than in ch: SUIT's `0`
   advance moves with weight, so a ch-based cap silently changes width
   between 400 and 900 while the reader's glyph count does not. */
.cover__statement {
  margin: 0;
  max-width: 13em;
  font-size: clamp(2.6rem, 7.2vw, 7rem);
  font-weight: 900;
  line-height: 1.06;   /* Korean display needs headroom above 1.0 */
  letter-spacing: -0.05em;   /* top of the optical ladder */
  text-wrap: balance;
}
.cover__statement strong { font-weight: inherit; }
.cover__foot {
  position: relative;
  z-index: 1;
  max-width: var(--page);
  width: 100%;
  margin: 0 auto;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  border-top: 1px solid var(--rule-strong);
  padding-top: 0.9rem;
}
.cover__scroll {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  padding: 0 0.9rem;
  border: 1px solid var(--ink);
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0.008em;
  text-decoration: none;
  background: var(--paper);
}
/* A line box of its own, so the chevron sits on the label's optical centre
   rather than hanging from its baseline. */
.cover__scroll-mark { font-size: 1.05em; line-height: 1; }
.cover__scroll:hover { background: var(--ink); color: var(--paper); }
/* The filled one is the action, set the way the bar sets it. */
.cover__scroll--act {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-on);
}
.cover__scroll--act:hover { background: var(--accent-deep); border-color: var(--accent-deep); color: var(--accent-on); }

/* Holds a name with spaces in it together across a line break. */
.nobr { white-space: nowrap; }

/* The way on from a finished page. A band at the foot rather than a spread of
   its own: the reading has stopped, and this is a hand held out, not a new
   thing to read. */
.sendoff {
  padding-top: clamp(2rem, 4.5vw, 3.25rem);
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
  border-top: 1px solid var(--rule);
}
.sendoff__row {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.75rem;
  margin: 0;
  max-width: var(--measure-wide);
  margin-left: auto;
}

/* --- 8. Contents -------------------------------------------- */

.contents {
  --plate-bg: var(--ink-flat);
  --plate-ink: var(--ink-on);
  --plate-rule: var(--ink-rule);
  --plate-accent: var(--ink-accent);
  --focus: var(--focus-ink);
}
.contents__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  border-bottom: 2px solid var(--plate-rule);
  padding-bottom: 0.8rem;
  margin-bottom: clamp(1.5rem, 4vw, 3rem);
}
.contents__title {
  font-size: clamp(1.6rem, 4.4vw, 3.2rem);
  font-weight: 900;
  letter-spacing: -0.04em;
}
.contents__kicker {
  margin: 0;
  font-size: var(--fs-meta);
  font-weight: 700;
  letter-spacing: 0.24em;
  color: var(--ink-accent);
}
.contents__list {
  margin: 0;
  padding: 0;
  list-style: none;
  columns: 2;
  column-gap: clamp(2rem, 5vw, 4.5rem);
}
.contents__row {
  border-bottom: 1px solid var(--plate-rule);
  break-inside: avoid;
}
.contents__link {
  display: grid;
  grid-template-columns: 3.2rem 1fr auto;
  align-items: center;
  gap: 0.9rem;
  min-height: 56px;
  padding: 0.8rem 0;
  text-decoration: none;
  color: inherit;
}
.contents__link:hover .contents__label { color: var(--ink-accent); }
.contents__no {
  font-size: 0.875rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  color: var(--ink-accent);
}
/* The contents is the issue's spine, and every label on it is a Korean
   chapter title: it grows with the canvas and takes the Hangul side of
   the tracking ladder. Weight stays at 600 so the row keeps answering
   to the 4.5:1 normal-text contrast bar rather than the 3:1 large-text
   one. */
.contents__label {
  font-size: clamp(1rem, 0.94rem + 0.26vw, 1.125rem);
  font-weight: 600;
  line-height: 1.42;
  letter-spacing: -0.01em;
}
.contents__label-text { display: block; text-wrap: pretty; }
.contents__subtitle {
  display: block;
  margin-top: 0.25rem;
  color: var(--ink-sub);
  font-size: var(--fs-meta);
  font-weight: 700;
  letter-spacing: 0.14em;
}

.contents__meter {
  display: block;
  height: 2px;
  background: var(--ink-rule-soft);
}
.contents__meter i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--ink-accent);
}

/* --- 9. Feature articles ------------------------------------ */

.feature { padding-top: clamp(4rem, 9vw, 9rem); }

.feature__head {
  position: relative;
  z-index: 1;
  margin-bottom: clamp(2rem, 5vw, 4rem);
}
.feature__folio {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 0 0 1.1rem;
  font-size: var(--fs-meta);
  font-weight: 700;
  letter-spacing: 0.2em;
  color: var(--plate-ink);
  opacity: 0.72;
}
.feature__folio i {
  display: block;
  width: clamp(2rem, 8vw, 6rem);
  height: 2px;
  background: var(--plate-accent);
  opacity: 1;
}
.feature__title {
  max-width: 15em;
  font-size: clamp(2rem, 5.4vw, 4.6rem);
  font-weight: 900;
  line-height: 1.02;
  letter-spacing: -0.042em;   /* display ladder, desktop step */
  text-wrap: balance;
}
.feature__title strong { font-weight: inherit; }
.feature__body { position: relative; z-index: 1; }

/* --- Emphasis ------------------------------------------------
   Three ranks, so that marking a line in twelve places still means something.
   All three take their colour from the plate they print on, because a chapter
   sets its own ink and its own accent and the same span appears on all of them.

   claim  the chapter's argument. A step up in size — enough to lift out of the
          column, not enough to leave it. Nothing else in the body changes size,
          so this is the only thing a skimming eye can catch.
   turn   where the chapter changes direction. The accent, at reading size.
   mark   a fact or a list worth stopping on. A band under the line rather than
          a wash behind it: the words keep the plate's own contrast, and the
          band survives a line break because the decoration is cloned. */
.emph { font-weight: 700; }
.emph--claim {
  font-size: 1.16em;
  letter-spacing: -0.014em;
}
.emph--turn { color: var(--plate-accent); }
.emph--mark {
  /* The band sits below the descenders rather than through them, which is what
     the padding buys — an inline box's padding does not touch the line height,
     so the column's leading is unchanged. */
  padding-bottom: 0.14em;
  background: linear-gradient(var(--plate-accent), var(--plate-accent))
              left bottom / 100% 0.16em no-repeat;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
@media print {
  /* On paper the accent is gone, so the band would print as a grey smear and
     the turn as flat black. Both fall back to the one mark paper keeps. */
  .emph--mark { background: none; border-bottom: 1.2pt solid #000; }
  .emph--turn { color: #000; }
}
/* The running Korean column: 37 syllables, read leading, read tracking.
   `pretty` is what keeps a paragraph from ending on a lone syllable.

   A feature body holds paragraphs in two shapes. The application spread builds
   its own <p> from block 57's line breaks, so those are direct children. The
   narrative's paragraphs are not: the composer moves each source block in
   whole, and the <p> sits inside the block that carries it. Addressing only
   `> p` therefore reached the application and never the story — eight of the
   ten chapters set at 73 syllables a line on a 1440 desktop, twice the measure
   this rule asks for. Both shapes are named together from here on. */
.feature__body > :is(p, .source-block) {
  max-width: var(--measure);
  margin-bottom: 1.5em;
  line-height: var(--lh-read);
  letter-spacing: var(--ls-read);
  text-wrap: pretty;
}
.feature__body > :is(p, .source-block):last-child { margin-bottom: 0; }

/* Vertical folio, desktop furniture only */
.feature__vfolio {
  position: absolute;
  top: 0;
  right: calc(var(--gutter) * -0.62);
  writing-mode: vertical-rl;
  font-size: var(--fs-meta);
  font-weight: 700;
  letter-spacing: 0.32em;
  color: var(--plate-ink);
  opacity: 0.5;
  display: none;
}
@media (min-width: 1180px) {
  .feature__vfolio { display: block; }
}

/* Editorial rhythm variants — each feature composes differently */
.feature--rule .feature__body > :is(p, .source-block) {
  border-left: 1px solid var(--plate-rule);
  padding-left: clamp(1rem, 2.4vw, 2.2rem);
  max-width: calc(var(--measure) + 2.2rem);
}
.feature--offset .feature__body { padding-left: 0; }
@media (min-width: 900px) {
  .feature--offset .feature__body > :is(p, .source-block) { margin-left: clamp(0rem, 14vw, 13rem); }
  .feature--offset .feature__title { margin-left: 0; }
  .feature--narrow .feature__body > :is(p, .source-block) { max-width: var(--measure-tight); margin-left: auto; margin-right: auto; }
  .feature--narrow .feature__head { text-align: center; }
  .feature--narrow .feature__title { margin: 0 auto; }
  .feature--narrow .feature__folio { justify-content: center; }
  .feature--wide .feature__body > :is(p, .source-block) { max-width: var(--measure-wide); font-size: 1.1875rem; }
  .feature--two .feature__body {
    column-count: 2;
    column-gap: clamp(2rem, 5vw, 4.5rem);
    column-rule: 1px solid var(--plate-rule);
  }
  .feature--two .feature__body > :is(p, .source-block) { max-width: none; }
  .feature--two .feature__body > .criteria { column-span: all; }
}

.feature__drop {
  position: absolute;
  left: calc(var(--gutter) * -1);
  top: -1.5rem;
  font-size: clamp(9rem, 22vw, 22rem);
  color: color-mix(in srgb, var(--plate-accent) 16%, transparent);
  z-index: 0;
}

/* Standfirst — the source's own bold lede.
   The selector carries one class more than `.feature--wide
   .feature__body > p`, which otherwise won the max-width cascade and
   left the lede running the wide column's full 44 syllables. */
.feature .feature__body > .standfirst,
.standfirst {
  max-width: 24em;
  font-size: clamp(1.25rem, 2.4vw, 1.9rem) !important;
  font-weight: 700;
  line-height: 1.44;
  letter-spacing: -0.022em;
  margin-bottom: 2em !important;
  text-wrap: balance;
}
.standfirst strong { font-weight: inherit; }

/* The invitation's foot: the one action the entry page offers, set on the
   reading column rather than against the cover's edge — and at the column's
   right edge, where the eye leaves a line. A forward action on the left is
   read as a heading for what follows; on the right it is read as the way out
   of what was just read, which is what this link is. */
.feature__onward {
  display: flex;
  justify-content: flex-end;
  max-width: var(--measure);
  margin: clamp(2rem, 4vw, 3rem) 0 0;
}
/* The site's own paragraphs are the source's shape, so they read as the source
   reads: the same column, the same leading, the same spacing. */
.feature--invitation .feature__head { margin-bottom: clamp(1.2rem, 3vw, 2rem); }

/* --- 11. Criteria grid (사람에 대한 기준) -------------------- */

.criteria {
  counter-reset: crit;
  display: grid;
  gap: 0;
  margin-top: clamp(1.5rem, 4vw, 3rem);
}
.criterion {
  border-top: 1px solid var(--plate-rule);
  padding: clamp(1.4rem, 3vw, 2.4rem) 0;
  display: grid;
  gap: 0.4rem 2.5rem;
}
@media (min-width: 900px) {
  .criterion { grid-template-columns: minmax(14rem, 22rem) 1fr; }
}
.criterion:last-child { border-bottom: 1px solid var(--plate-rule); }
.criterion__title {
  counter-increment: crit;
  margin: 0 !important;
  font-size: clamp(1.25rem, 2.4vw, 1.75rem) !important;
  font-weight: 800;
  letter-spacing: -0.028em;
  line-height: 1.28;
  align-self: start;
  text-wrap: pretty;
}
.criterion__title strong { font-weight: inherit; }
.criterion__title::before {
  content: "0" counter(crit);
  display: block;
  margin-bottom: 0.45rem;
  font-size: var(--fs-meta);
  font-weight: 800;
  letter-spacing: 0.2em;
  color: var(--plate-accent);
}
.criterion__body {
  margin: 0 !important;
  max-width: var(--measure);
  line-height: var(--lh-read);
  letter-spacing: var(--ls-read);
  text-wrap: pretty;
}
.feature--people .feature__body > :is(p, .source-block) { max-width: var(--measure); }
.feature--people .criterion__title {
  padding-bottom: 0.35rem;
  background-image: linear-gradient(var(--mark), var(--mark));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 0.42rem;
}

/* --- 12. Application spread (back of book) ------------------ */

.feature--apply .feature__body > :is(p, .source-block) { max-width: var(--measure); }
.subhead {
  margin: clamp(2.4rem, 5vw, 4rem) 0 1.2rem !important;
  padding-top: 1.1rem;
  border-top: 2px solid var(--plate-accent);
  font-size: clamp(1.15rem, 2.2vw, 1.6rem) !important;
  font-weight: 800;
  letter-spacing: -0.02em;
  max-width: none !important;
  text-wrap: pretty;
}
.subhead strong { font-weight: inherit; }
/* The three submission rows are the most action-critical text on the
   page and were the only reading block with no measure at all: at 1440
   they ran the full 1,325px spread, about 78 syllables to the line.
   The box is capped so the text inside it lands on the reading column. */
.submission {
  display: grid;
  gap: 0;
  margin: 1.4rem 0 2rem;
  border: 1px solid var(--plate-rule);
  max-width: calc(var(--measure) + 3.2rem);
}
.submission > p {
  margin: 0 !important;
  padding: 1rem clamp(1rem, 2.2vw, 1.6rem);
  max-width: none !important;
  font-size: 1.0625rem;
  line-height: var(--lh-read-list);
  letter-spacing: var(--ls-read);
  text-wrap: pretty;
}
.submission > p + p { border-top: 1px solid var(--plate-rule); }
/* The composer splits each row into the document's own label — colon included —
   and the value after it, and strips the space it moved across. Without these
   two rules the two spans sit flush and the rows read 접수 이메일:ceo@…, which
   is not what the document says. The label is the term, so it holds its own
   column where the row has the width for one and steps above the value where
   it does not. */
.submission__term {
  font-weight: 700;
  flex: 0 0 auto;
}
.submission__value { flex: 1 1 12rem; min-width: 0; }
.submission__row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.1rem 0.6rem;
}
.submission a {
  color: var(--plate-accent);
  font-weight: 700;
  text-underline-offset: 4px;
}
/* The one address on the site, and on a phone it was a 21px-high target in a
   row with room to spare. */
.submission a[href^="mailto:"] {
  display: inline-block;
  padding: 0.55rem 0;
  line-height: 1.3;
}

/* --- 13. Role index ----------------------------------------- */

.role-index {
  --plate-bg: var(--paper);
  padding-top: clamp(3rem, 6vw, 5rem);
  border-top: 4px solid var(--ink);
}
.role-index__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  margin-bottom: clamp(1.5rem, 3vw, 2.5rem);
}
.role-index__title {
  font-size: clamp(2rem, 5.4vw, 4.4rem);
  font-weight: 900;
  letter-spacing: -0.045em;
  line-height: 0.98;
}
.role-index__title small {
  display: block;
  font-size: clamp(0.7rem, 1.1vw, 0.8125rem);
  font-weight: 700;
  letter-spacing: 0.26em;
  color: var(--accent);
  margin-bottom: 0.6rem;
}

/* Toolbar — full-bleed sticky strip */
.rolebar {
  position: sticky;
  /* app.js measures the live folio bar; 3.4375rem is the pre-script value. */
  top: var(--bar-h, 3.4375rem);
  z-index: 40;
  background: var(--paper);
  border-top: 2px solid var(--ink);
  border-bottom: 1px solid var(--rule);
  margin: 0 calc(var(--pad-r) * -1) clamp(1.5rem, 3vw, 2.5rem) calc(var(--pad-l) * -1);
  padding: 0.75rem var(--pad-r) 0.75rem var(--pad-l);
}
.rolebar__in {
  max-width: var(--page);
  margin: 0 auto;
}
.rolebar__search { display: flex; align-items: center; gap: 0.6rem; }
/* Hangul label: micro-label size, Hangul tracking. */
.rolebar__search label {
  font-size: var(--fs-meta);
  font-weight: 800;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
.rolebar__input {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  padding: 0.55rem 0.85rem;
  border: 1px solid var(--field-rule);
  background: var(--field-bg);
  color: var(--field-ink);
  font: inherit;
  font-size: 1rem;
  border-radius: 0;
}
.rolebar__input::placeholder { color: var(--field-hint); }
.rolebar__status {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.9rem;
  margin-top: 0.7rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--ink-soft);
}
.rolebar__count { font-weight: 800; color: var(--ink); }
.rolebar__count b { color: var(--accent); }
.linkbtn {
  min-height: 44px;
  padding: 0 0.75rem;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 0.875rem;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 4px;
  cursor: pointer;
}
.linkbtn:hover { color: var(--accent); }
.linkbtn[hidden] { display: none; }

/* The one group the document heads: 3. 교육 기획/개발 and its five tracks. */
.rolegroup {
  position: relative;
  padding: clamp(2rem, 4vw, 3.4rem) 0 0;
  border-top: 1px solid var(--rule);
  overflow: clip;
  scroll-margin-top: var(--sticky-offset, 9rem);
}
.rolegroup[hidden] { display: none; }
.rolegroup__title {
  position: relative;
  z-index: 1;
  max-width: 26ch;
  margin-bottom: 1.2rem;
  font-size: clamp(1.35rem, 2.9vw, 2.3rem);
  font-weight: 900;
  letter-spacing: -0.03em;
  text-wrap: pretty;
}
.rolegroup__title strong { font-weight: inherit; }
/* The group's own intro paragraph, from the document. It reads as reading
   matter, so it takes the reading column and the reading leading. */
.rolegroup__intro {
  position: relative;
  z-index: 1;
  max-width: var(--measure);
  margin: 0 0 1.4rem;
  line-height: var(--lh-read);
  letter-spacing: var(--ls-read);
  color: var(--ink-soft);
  text-wrap: pretty;
}
/* The five tracks hang under the heading that owns them. The document says so
   in its numbering — 3-1 against 4 — but the rows are set at the same step as
   the top-level positions, and a step is not what tells them apart: containment
   is. A rule and an indent say it without inventing a fifth type size. */
.rolegroup__list {
  position: relative;
  z-index: 1;
  border-left: 2px solid var(--rule);
  padding-left: clamp(0.85rem, 2.6vw, 1.6rem);
}

/* Position rows */
.role {
  border-top: 1px solid var(--rule);
  scroll-margin-top: var(--sticky-offset, 9rem);
}
.role:last-child { border-bottom: 1px solid var(--rule); }
.role[hidden] { display: none; }
.role__h {
  margin: 0;
  font-size: inherit;
  font-weight: inherit;
  letter-spacing: normal;
  scroll-margin-top: var(--sticky-offset, 9rem);
}
.role__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  width: 100%;
  min-height: 56px;
  padding: 1.05rem 0 0.4rem;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
/* The default 3px outset ring would strike through the kicker line that
   follows the toggle, so this one control rings inside its own box. */
.role__toggle:focus-visible { outline-offset: -3px; }
.role__toggle:hover .role__name { color: var(--accent); }
/* The position name is the most-scanned string on the page, so on a
   phone it now outranks body copy (18px against 17.57px) instead of
   sitting half a pixel below it. `pretty` keeps long role names off a
   one- or two-syllable last line. */
.role__name {
  font-size: clamp(1.125rem, 1.6vw, 1.3125rem);
  font-weight: 800;
  letter-spacing: -0.022em;
  line-height: 1.34;
  text-wrap: pretty;
}
.role__name strong { font-weight: inherit; }
/* Eleven of the twelve positions are Headers in the document and arrive as
   text. The twelfth is a Para, so the promoted block brings its <p> along and
   that paragraph's margin made the one row 19px taller than its siblings. */
.role__name p { margin: 0; }
.role__mark {
  position: relative;
  width: 30px;
  height: 30px;
  border: 1px solid var(--rule-strong);
  flex: none;
}
.role__mark::before,
.role__mark::after {
  content: "";
  position: absolute;
  background: var(--ink);
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
.role__mark::before { width: 13px; height: 2px; }
.role__mark::after { width: 2px; height: 13px; }
.role__toggle[aria-expanded="true"] .role__mark { background: var(--accent); border-color: var(--accent); }
.role__toggle[aria-expanded="true"] .role__mark::before,
.role__toggle[aria-expanded="true"] .role__mark::after { background: var(--accent-on); }
.role__toggle[aria-expanded="true"] .role__mark::after { display: none; }

/* A container width, not a reading measure: the JD meta table wants
   the room. The text inside carries the reading measure itself. */
.role__panel {
  padding: 0 0 clamp(1.75rem, 3vw, 2.75rem);
  max-width: 52rem;
}
.role__panel[hidden] { display: none; }
.role__panel > p {
  max-width: var(--measure);
  font-size: 1.0625rem;
  line-height: var(--lh-read);
  letter-spacing: var(--ls-read);
  text-wrap: pretty;
}
.role__panel table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 1.5rem;
  font-size: 1rem;
  text-align: left;
}
.role__panel th,
.role__panel td {
  border-top: 1px solid var(--rule);
  padding: 0.7rem 0.9rem 0.7rem 0;
  vertical-align: top;
  line-height: var(--lh-read-list);
  letter-spacing: var(--ls-read);
  text-wrap: pretty;
}
.role__panel thead th { border-top: 2px solid var(--ink); }
.role__panel tr > *:first-child {
  width: 8.5rem;
  font-weight: 700;
  color: var(--ink-soft);
  white-space: nowrap;
}
.role__panel tr > *:first-child strong { font-weight: 700; }
/* Source-bearing Korean section headings (주요 업무 / 자격 요건 /
   우대 사항). They were set as a 13px Latin-style kicker at 0.2em,
   which pulls Hangul syllable blocks apart before it separates the
   words. Now a proper subhead: one step up in size, tracking off. */
.role__panel h3 {
  margin: 1.9rem 0 0.75rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--rule);
  font-size: 0.9375rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: var(--accent);
}
.role__panel h3 strong { font-weight: inherit; }
.role__panel ul { margin: 0 0 0.5rem; }
/* Requirement bullets took the panel's container width, running to
   ~49 syllables a line. They are reading text and now take the
   reading measure. */
.role__panel li {
  position: relative;
  padding-left: 1.15rem;
  margin-bottom: 0.5rem;
  font-size: 1.0625rem;
  line-height: var(--lh-read-list);
  letter-spacing: var(--ls-read);
  max-width: var(--measure);
  text-wrap: pretty;
}
.role__panel li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.72em;
  width: 6px;
  height: 6px;
  background: var(--mark);
  outline: 1px solid var(--ink);
}

.role-empty {
  padding: 3rem 0;
  border-top: 1px solid var(--rule);
  max-width: var(--measure);
  font-size: 1.0625rem;
  line-height: var(--lh-read);
  letter-spacing: var(--ls-read);
  color: var(--ink-soft);
  text-wrap: pretty;
}
.role-empty[hidden] { display: none; }

/* --- 13b. The contents drawer -------------------------------- */

/* The handle sits on the foot of the screen for the whole of the story, names
   the chapter the reader is in, and opens the contents over the page. */
.contents-handle {
  position: fixed;
  z-index: 55;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  min-height: 44px;
  padding: 0.6rem var(--pad-r) calc(0.6rem + env(safe-area-inset-bottom)) var(--pad-l);
  border: 0;
  border-top: 2px solid var(--ink);
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: 0.875rem;
  font-weight: 700;
  text-align: left;
  cursor: pointer;
  box-shadow: 0 -14px 18px -16px var(--rail-shadow);
}
.contents-handle__label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  letter-spacing: 0.004em;
}
.contents-handle__count {
  flex: none;
  font-size: var(--fs-meta);
  font-weight: 800;
  letter-spacing: 0.14em;
  color: var(--accent);
}
/* A chevron drawn from the same two rules the role toggles use. */
.contents-handle__mark {
  flex: none;
  width: 26px;
  height: 26px;
  border: 1px solid var(--rule-strong);
  position: relative;
}
.contents-handle__mark::before,
.contents-handle__mark::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 9px;
  height: 2px;
  background: var(--ink);
}
.contents-handle__mark::before { transform: translate(-72%, -50%) rotate(-45deg); }
.contents-handle__mark::after { transform: translate(-28%, -50%) rotate(45deg); }
.contents-handle:hover { background: var(--paper-deep); }

/* The page keeps the handle's height clear so the colophon is never behind it. */
html.has-contents-drawer .colophon {
  padding-bottom: calc(clamp(2.5rem, 6vw, 4.5rem) + env(safe-area-inset-bottom) + 3.5rem);
}

.contents-drawer {
  width: min(100% - 1.5rem, 44rem);
  max-width: none;
  max-height: calc(100svh - 3rem);
  margin: auto auto 0.75rem;
  padding: 0;
  overflow: hidden;
  border: 2px solid var(--ink);
  background: var(--ink-flat);
  color: var(--ink-on);
  --focus: var(--focus-ink);
}
.contents-drawer::backdrop { background: rgba(16, 22, 19, 0.72); }
.contents-drawer .contents {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  max-height: inherit;
}
.contents-drawer .contents__in {
  display: contents;
}
.contents-drawer .contents__head {
  padding: 0.9rem var(--pad-r) 0.8rem var(--pad-l);
  margin-bottom: 0;
}
/* No columns inside the drawer, rather than one. A multi-column box with a
   definite height puts whatever does not fit into overflow columns beside it,
   and `column-count: 1` still leaves it a multi-column box — the last four rows,
   including the two places the reader can actually go next, ended up past the
   right edge where no scrollbar reaches. `auto` takes the context away. */
.contents-drawer .contents__list {
  columns: auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 var(--pad-r) calc(0.5rem + env(safe-area-inset-bottom)) var(--pad-l);
}
.contents__close {
  min-width: 44px;
  min-height: 44px;
  margin-left: auto;
  padding: 0 0.75rem;
  border: 1px solid var(--ink-rule-strong);
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 700;
  cursor: pointer;
}
.contents__close:hover { background: var(--ink-on); color: var(--ink-flat); }
/* Where the reader is, in the map they just opened. */
.contents__row[aria-current="location"] .contents__label { color: var(--ink-accent); }
.contents__row[aria-current="location"] .contents__no { color: var(--ink-on); }

/* --- 14. Colophon ------------------------------------------- */

.colophon {
  background: var(--ink-flat);
  color: var(--ink-on);
  --focus: var(--focus-ink);
  padding: clamp(2.5rem, 6vw, 4.5rem) var(--pad-r)
           calc(clamp(2.5rem, 6vw, 4.5rem) + env(safe-area-inset-bottom)) var(--pad-l);
}
.colophon__in {
  max-width: var(--page);
  margin: 0 auto;
  display: grid;
  gap: 0.8rem;
}
.colophon__in {
  align-items: end;
  grid-template-columns: auto 1fr;
}
.colophon__flag { margin: 0; --mark-h: 1.5rem; }
.colophon__reach { margin: 0; justify-self: end; font-size: 0.9375rem; }
.colophon__reach a {
  display: inline-block;
  min-height: 44px;
  padding: 0.6rem 0;
  color: var(--ink-accent);
  font-weight: 700;
  text-underline-offset: 4px;
}
@media (max-width: 520px) {
  .colophon__in { grid-template-columns: 1fr; }
  .colophon__reach { justify-self: start; }
}
.colophon__flag .brandmark { font-size: 1.5rem; font-weight: 900; letter-spacing: -0.04em; }
.colophon__flag .wordmark__ident { font-size: 0.625rem; }

/* The wrong-address page is the one page short enough to leave the colophon
   floating above bare ground, so it holds the screen and pushes it down. */
body[data-page="notfound"] {
  display: flex;
  flex-direction: column;
  min-height: 100svh;
}
body[data-page="notfound"] main { flex: 1 0 auto; }

/* --- 15. No-JS reading document ----------------------------- */

html:not(.js) .verbatim-source {
  display: block;
  max-width: 44rem;
  margin: 0 auto;
  padding: clamp(2rem, 6vw, 4.5rem) var(--pad-r)
           calc(5rem + env(safe-area-inset-bottom)) var(--pad-l);
}
/* The no-JS state is a reading document, so it takes the reading
   leading and tracking rather than the document defaults. */
html:not(.js) .verbatim-source > p,
html:not(.js) .verbatim-source > ul > li {
  max-width: none;
  line-height: var(--lh-read);
  letter-spacing: var(--ls-read);
  text-wrap: pretty;
}
html:not(.js) .verbatim-source > h1 {
  margin: 3.2rem 0 1.2rem;
  padding-top: 1rem;
  border-top: 3px solid var(--ink);
  font-size: clamp(1.5rem, 4vw, 2.4rem);
  font-weight: 900;
}
html:not(.js) .verbatim-source > h2 {
  margin: 2.4rem 0 0.8rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--rule-strong);
  font-size: clamp(1.15rem, 2.6vw, 1.5rem);
}
html:not(.js) .verbatim-source > h3 {
  margin: 1.6rem 0 0.6rem;
  font-size: 0.9375rem;
  letter-spacing: 0.04em;
  color: var(--accent);
}
html:not(.js) .verbatim-source > ul { margin-bottom: 1.4rem; }
html:not(.js) .verbatim-source > ul > li {
  position: relative;
  padding-left: 1.15rem;
  margin-bottom: 0.5rem;
}
html:not(.js) .verbatim-source > ul > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.72em;
  width: 6px;
  height: 6px;
  background: var(--mark);
  outline: 1px solid var(--ink);
}
html:not(.js) .verbatim-source > table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 1.6rem;
  text-align: left;
  font-size: 1rem;
}
html:not(.js) .verbatim-source > table th,
html:not(.js) .verbatim-source > table td {
  border-top: 1px solid var(--rule);
  padding: 0.6rem 0.8rem 0.6rem 0;
  vertical-align: top;
}
html:not(.js) .verbatim-source > blockquote {
  margin: 2rem 0;
  padding-left: 1.2rem;
  border-left: 4px solid var(--accent);
  font-size: 1.25rem;
  font-weight: 700;
}

/* --- 16. Responsive recomposition --------------------------- */

/* Tier 1 — the spread collapses to a single column. */
@media (max-width: 900px) {
  .folio-bar__run { display: none; }
  .folio-bar__nav a { padding: 0 0.55rem; font-size: 0.8125rem; }
  .cover__glyph { font-size: 15rem; right: -0.16em; bottom: -0.1em; }
  /* Middle rung of the display ladder: less type, less tracking. */
  .cover__statement {
    max-width: none;
    font-size: clamp(2.1rem, 9.4vw, 3.4rem);
    letter-spacing: -0.04em;
  }
  .feature__title { line-height: 1.06; letter-spacing: -0.036em; }
  .contents__list { columns: 1; }
  .feature--two .feature__body { column-count: 1; }
  .feature__drop { display: none; }
  .role__panel tr > *:first-child { width: 6.2rem; white-space: normal; }
}

/* ------------------------------------------------------------
   Tier 2 — portrait phone (covers the 390 / 402 / 412 / 440
   viewport contract with headroom).

   This tier recomposes rather than shrinks:
     - the cover becomes flag / crop numeral / hero / colophon rule
     - the filter toolbar becomes a compact sticky strip whose seven
       division chips ride a contained horizontal rail
     - JD tables stack into label-over-value pairs
     - no element carrying canonical source text renders below 16px
   ------------------------------------------------------------ */
@media (max-width: 640px) {
  /* This document's chapters run three to five paragraphs. The borrowed
     measurements were set for shorter ones, so on a phone a spread has to give
     back the room it does not need: less air around the plate, a tighter step
     from the head to the body, and reading type that keeps its leading without
     spending a line and a half on every sentence. */
  /* Forty characters of tracked-out capitals do not fit a phone's measure at
     the desktop's letter-spacing. The kicker is one line or it is noise. */
  .cover__flag .cover__issue {
    font-size: clamp(0.625rem, 2.6vw, 0.75rem);
    letter-spacing: 0.1em;
    white-space: nowrap;
  }

  .spread { padding-top: 2rem; padding-bottom: 2rem; }
  .feature__head { margin-bottom: 1.4rem; }
  /* Leading is not set here: running prose takes --lh-read through the
     paragraph rule. This container carried 1.58 only because that rule could
     not reach the narrative, and removing it now moves nothing. */
  .feature__body { font-size: 1.0625rem; }
  .feature__body > * + * { margin-top: 0.9em; }


  /* --- 16.0 reading leading --------------------------------- */

  /* The phone column runs about 22 syllables against the desktop's 37,
     so the eye returns sooner and needs less lead. The saving is spent
     on glyph size (--fs-body is 17.57px here, up from 17.09px), which
     leaves the line box within a rounding error of where it was while
     the type itself is ~3% larger. */
  :root {
    --lh-read: 1.74;
    --lh-read-list: 1.64;
  }

  /* --- 16.0b the display ladder ------------------------------ */

  /* A phone has room for four steps above the body, not for the nine
     sizes the desktop ladder collapses into here. Measured at 402px, the
     page used to set the cover at 36 and the chapter title at 32 — one
     step wearing two sizes — and then ran section head 21.6, criterion 20,
     lede 20, application subhead 18.4, position 18, body 17 and kicker 16
     as a second undifferentiated cluster.

     One ladder replaces both, geometric at about 1.26 from the body up, so
     each step is legible as a step rather than as a rounding difference:

       본문 17  ->  소제목 21.5  ->  제목 28  ->  표지 40   (at 402px)

     Every rung is fluid across 360-440 and the ratios hold at both ends. */
  :root {
    --step-cover: clamp(2.15rem, 9.9vw, 2.85rem);   /* the one hero statement */
    --step-title: clamp(1.6rem, 6.95vw, 2.05rem);   /* a spread's own head */
    --step-sub: clamp(1.3rem, 5.35vw, 1.45rem);     /* heads inside a spread */
  }

  /* Spread heads: the chapter, the contents, the role index. */
  .feature__title,
  .contents__title,
  .role-index__title { font-size: var(--step-title); }

  /* Section heads: the division, the criterion, the application subhead,
     the position name, and the source's own lede. They never appear on one
     screen in a way that needs telling apart by size — the criterion carries
     its numeral and underline, the division its watermark, the position its
     rule and toggle — so they share one rung instead of spreading over five
     sizes within three pixels of each other. */
  .rolegroup__title,
  .role__name { font-size: var(--step-sub); }
  /* These three set inside .feature__body, where the paragraph rules would
     otherwise win the cascade; they carry the !important their base rules do. */
  .criterion__title,
  .subhead,
  .feature .feature__body > .standfirst,
  .standfirst { font-size: var(--step-sub) !important; }

  /* --- 16.1 cover ------------------------------------------- */

  /* Fill exactly the space under the folio bar: no clipped hero,
     no scroll-to-nowhere gap. svh keeps it stable while an Android
     browser bar collapses. */
  .cover {
    min-height: calc(100vh - var(--bar-h, 3.5rem));
    min-height: calc(100svh - var(--bar-h, 3.5rem));
    padding-top: clamp(1.5rem, 3.5svh, 2.5rem);
    padding-bottom: max(clamp(1.5rem, 3svh, 2.25rem),
                        calc(env(safe-area-inset-bottom) + 1rem));
  }
  /* A cover that fills the screen exactly ends exactly at the fold, and a
     phone gives a reader no other way to learn that a page continues: no
     scrollbar, no page edge, nothing under the thumb. So a cover with a page
     under it keeps a strip back — enough for the next spread's folio line and
     the first two lines of its first paragraph, which is a sentence beginning
     mid-air and the plainest invitation to scroll there is. */
  .cover--continues {
    --peek: clamp(6rem, 15svh, 9.5rem);
    min-height: calc(100vh - var(--bar-h, 3.5rem) - var(--peek));
    min-height: calc(100svh - var(--bar-h, 3.5rem) - var(--peek));
  }
  .cover__in { gap: clamp(1rem, 2.5svh, 2rem); }
  .cover__flag { padding-bottom: 0.55rem; }
  /* Kicker, hero and lede read as one block from the top of the column down.
     The lede is the last thing the cover says, so nothing is parked below it:
     what follows it is the next spread, not room. */
  .cover__statement {
    margin-bottom: clamp(0.4rem, 2svh, 1.2rem);
    font-size: var(--step-cover);
    line-height: 1.12;
    letter-spacing: -0.03em;   /* bottom rung of the display ladder */
  }
  /* Portrait turns the numeral into the cover's image: it is cropped by
     the right edge, carries the field between the flag rule and the hero,
     and overprints the hero's top lines instead of crossing the foot,
     where it would sit over an essential label. Sized against both axes
     so a taller screen gets a taller numeral, not a taller void. */
  .cover__glyph {
    bottom: clamp(10rem, 22svh, 14rem);
    left: -0.05em;
    right: auto;
    /* Two Latin capitals are narrower than two digits at the same size, so
       the cover's plate takes a larger one: the crop by both page edges is the
       composition, and a mark that stops short of them reads as a watermark
       floating in the page instead. */
    font-size: clamp(22rem, max(108vw, 50svh), 34rem);
  }
  /* The reserve above the cover's foot exists to keep the numeral off the
     action printed there. A cover that hands its action to the invitation has
     no such label, so the numeral runs to the foot and the strip that used to
     be blank — the strip that made the page look finished — is image. */
  .cover--continues .cover__glyph { bottom: clamp(0.5rem, 2svh, 1.5rem); }
  /* One action, at the foot's right edge, clear of the cropped numeral. */
  .cover__foot { align-items: center; }

  /* --- 16.2 folio bar --------------------------------------- */

  /* The name stays. It is the reason the mark is here, and a phone is where
     most readers will meet it — so the bar gives back gutters and label width
     instead of the identity. */
  .folio-bar__in { gap: 0.5rem; padding-left: 0.9rem; padding-right: 0.9rem; }
  .folio-bar__flag { gap: 0.4rem; }
  .folio-bar__flag { --mark-h: 1.05rem; }
  .folio-bar__flag .brandmark { font-size: 0.9375rem; }
  .folio-bar__flag .wordmark__ident {
    padding-left: 0.4rem;
    font-size: 0.5rem;
    letter-spacing: 0.1em;
  }
  .folio-bar__nav { gap: 0; }
  .folio-bar__nav a { padding: 0 0.42rem; font-size: 0.75rem; }
  .folio-bar__act { margin-left: 0.25rem; padding: 0 0.55rem; }

  /* --- 16.3 features ---------------------------------------- */

  .feature__folio { flex-wrap: wrap; row-gap: 0.35rem; }
  .feature__title { max-width: none; line-height: 1.12; letter-spacing: -0.03em; }
  .standfirst { max-width: none; line-height: 1.5; }
  .contents__link { grid-template-columns: 2.4rem minmax(0, 1fr); gap: 0.75rem; }
  /* --- 16.4 모집 포지션 toolbar ------------------------------ */

  /* Sticky again on phones: with the chips on a rail the strip is a
     compact band under the folio bar instead of the half-viewport
     block that wrapping chips used to produce. */
  .rolebar {
    position: sticky;
    padding-top: 0.45rem;
    padding-bottom: 0.45rem;
    box-shadow: 0 12px 16px -14px var(--rail-shadow);
  }
  .rolebar__search { gap: 0.5rem; }
  .rolebar__search label { font-size: 0.75rem; letter-spacing: 0.02em; }
  .rolebar__input { padding: 0.4rem 0.75rem; }


  /* Count owns its own line, the three actions share the next one. */
  .rolebar__status {
    gap: 0 0.3rem;
    margin-top: 0.35rem;
    font-size: 0.8125rem;
  }
  .rolebar__count { flex: 1 0 100%; line-height: 1.4; }
  .linkbtn { padding: 0 0.5rem; font-size: 0.8125rem; }

  /* --- 16.5 anchor clearance -------------------------------- */

  /* One offset per target, never two. The document only pads for the
     folio bar; rows that also live under the filter strip carry that
     extra clearance themselves. */
  html { scroll-padding-top: var(--bar-offset, 4.5rem); }
  .spread { scroll-margin-top: 1rem; }
  .rolegroup,
  .role,
  .role__h { scroll-margin-top: calc(var(--rolebar-offset, 0px) + 0.75rem); }

  /* --- 16.6 role rows and JD panels ------------------------- */

  .role-index__head { margin-bottom: 1.25rem; }
  .role__toggle { gap: 1rem; }
  .role__panel h3 {
    font-size: var(--fs-source-min);
    letter-spacing: 0.02em;
  }
  /* JD meta tables stack into label-over-value pairs. */
  .role__panel table,
  .role__panel thead,
  .role__panel tbody,
  .role__panel tr,
  .role__panel th,
  .role__panel td { display: block; width: auto; }
  .role__panel table { font-size: var(--fs-source-min); }
  .role__panel tr { border-top: 1px solid var(--rule); padding: 0.6rem 0; }
  .role__panel thead tr { border-top: 2px solid var(--ink); }
  .role__panel th,
  .role__panel td { border: 0; padding: 0.1rem 0; }
  /* The stacked row already carries the rule, so the head cell must
     not print a second one on top of it. */
  .role__panel thead th { border-top: 0; }
  /* Label over value: the pair needs a visible step between them, and
     the label is Hangul, so it takes Hangul tracking. */
  .role__panel tr > *:first-child {
    width: auto;
    font-size: var(--fs-source-min);
    letter-spacing: 0.01em;
    line-height: 1.45;
    padding-bottom: 0.2rem;
    color: var(--accent);
  }


  /* --- 16.7 furniture --------------------------------------- */

  .regmark { width: 18px; height: 18px; }
}

/* --- 17. Motion --------------------------------------------- */

/* Content is fully visible by default; motion is opt-in only. */
@media (prefers-reduced-motion: no-preference) {
  .rise {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 620ms cubic-bezier(0.2, 0.7, 0.2, 1),
                transform 620ms cubic-bezier(0.2, 0.7, 0.2, 1);
  }
  .rise.is-in { opacity: 1; transform: none; }
  .folio-bar__progress i { transition: width 160ms linear; }
  .contents__meter i { transition: width 240ms linear; }
  .role__mark,
  .cover__scroll { transition: background-color 160ms ease, color 160ms ease, border-color 160ms ease; }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .rise { opacity: 1 !important; transform: none !important; }
}

/* --- 18. Print ---------------------------------------------- */

@media print {
  @page { margin: 16mm; }
  html, body {
    background: #fff !important;
    color: #000 !important;
    font-size: 10.5pt;
    line-height: 1.6;
  }
  /* Controls do not work on paper. These were only being repainted, so a saved
     PDF opened on a page of navigation and a search box nobody can type into,
     and the toggles printed as empty squares. */
  .folio-bar,
  .skiplinks,
  .rolebar,
  .contents,
  .contents-handle,
  .cover__scroll,
  .role__mark { display: none !important; }
  .cover__glyph,
  .feature__drop,
  .spread,
  .cover,
  .colophon {
    background: #fff !important;
    color: #000 !important;
    padding: 0 0 12pt !important;
    border-color: #000 !important;
    min-height: 0 !important;
  }
  .contents__kicker,
  .contents__no,
  .role__panel h3,
  .role-index__title small { color: #000 !important; }
  .feature { padding-top: 18pt; }
  /* Break between chapters, not before the first one — a page-break-before on
     every .feature put a blank sheet in front of every document. */
  .feature + .feature { page-break-before: always; }
  .cover { page-break-after: always; }
  .feature__title { font-size: 20pt; }
  .cover__statement { font-size: 26pt; }
  .role__panel[hidden] { display: block !important; }
  /* A JD is routinely taller than a sheet, so keeping each one whole spent a
     page per position: twelve positions took 25 sheets. Let them flow. */
  .role { border-top: 0.5pt solid #000; }
  .role__panel li::before { background: #000 !important; outline: 0 !important; }
  a { text-decoration: none; }
  .rise { opacity: 1 !important; transform: none !important; }
}
