/* ═══════════════════════════════════════════════════════════════
   scenes.css — sticky scroll scenes and their visualizations
   Scene layout contract (shared by #initial and #services):
     .scene > .scene-grid > .scene-visual (sticky) + .scene-copy (flow)
   JS sets  data-stage  on .scene  and  .is-active  on .step / stage svg.
   ═══════════════════════════════════════════════════════════════ */

.scene{ position:relative; padding:0 var(--pad); }
.scene-grid{
  width:100%; max-width:var(--rail); margin:0 auto;
  display:grid; grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  gap:clamp(32px,5vw,80px);
  align-items:start;
}

/* ── sticky visual column ────────────────────────────────────── */
.scene-visual{
  position:sticky; top:var(--bar-h);
  height:calc(100vh - var(--bar-h));
  height:calc(100svh - var(--bar-h));
  display:flex; align-items:center;
}
.visual-frame{
  position:relative; width:100%;
  aspect-ratio:1/1;
  max-height:calc(100vh - var(--bar-h) - 96px);
  max-height:calc(100svh - var(--bar-h) - 96px);
  margin-inline:auto;
}
.visual-frame > svg,
.stage-deck{ position:absolute; inset:0; width:100%; height:100%; }

.visual-caption{
  position:absolute; left:0; bottom:-6px;
  display:flex; align-items:baseline; gap:12px;
}
.vc-step{
  font-family:var(--mono); font-size:11px; letter-spacing:.2em; color:var(--acc);
}
.vc-label{
  font-family:var(--mono); font-size:11px; letter-spacing:.2em;
  text-transform:uppercase; color:var(--dim);
}

/* ── copy column ─────────────────────────────────────────────── */
.scene-copy{ padding:clamp(56px,10vh,120px) 0 clamp(56px,10vh,120px); }

.step{
  min-height:76vh;
  display:flex; flex-direction:column; justify-content:center;
  max-width:var(--measure);
  opacity:.26; filter:saturate(.5);
  transition:opacity .5s var(--ease), filter .5s var(--ease);
}
.step.is-active{ opacity:1; filter:none; }

.step-kicker{
  font-family:var(--mono); font-size:11px; letter-spacing:.24em;
  color:var(--acc); margin-bottom:16px;
}
.step h3{
  font-size:clamp(24px,3.1vw,38px); line-height:1.16; letter-spacing:-.02em;
  font-weight:600; color:var(--text); margin-bottom:18px;
  display:flex; align-items:center; gap:12px; flex-wrap:wrap;
}
.step p{ font-size:clamp(15px,1.25vw,17px); line-height:1.80; color:var(--body); }
html[data-lang="ko"] .step h3{ line-height:1.34; letter-spacing:-.024em; }
html[data-lang="ko"] .step p{ line-height:1.88; }

.step-flow{
  margin-top:24px !important; display:flex; align-items:center;
  gap:10px; flex-wrap:wrap;
}
.step-flow b{
  font-family:var(--mono); font-size:11px; letter-spacing:.13em;
  text-transform:uppercase; font-weight:500; color:var(--text);
  padding:6px 11px; border:1px solid var(--line); border-radius:4px;
  background:rgba(62,224,200,.035);
}
.step-flow i{ color:var(--acc); font-style:normal; font-size:13px; }

.step-note{
  margin-top:16px !important; font-size:13.5px !important; color:var(--dim) !important;
  padding-left:14px; border-left:2px solid var(--acc-dark);
}

.chips{ display:flex; flex-wrap:wrap; gap:8px; margin-top:24px; }
.chips li{
  font-family:var(--mono); font-size:10.5px; letter-spacing:.12em;
  text-transform:uppercase; color:var(--dim);
  padding:5px 10px; border:1px solid var(--line-soft); border-radius:100px;
}
.chips li.is-out{ color:var(--acc); border-color:rgba(62,224,200,.28); }

.tag{
  font-family:var(--mono); font-size:10px; letter-spacing:.16em;
  text-transform:uppercase; font-weight:500;
  padding:5px 10px; border-radius:100px; white-space:nowrap;
}
.tag-soon{ color:var(--warm); border:1px solid rgba(240,180,90,.32); background:rgba(240,180,90,.07); }

/* ═══ SCENE 03 — INITIAL STEPS ═══════════════════════════════ */
.stage-deck{ position:absolute; inset:0; }
.stage-svg{
  position:absolute; inset:0; width:100%; height:100%;
  opacity:0; transform:scale(.965); pointer-events:none;
  transition:opacity .6s var(--ease), transform .7s var(--ease-out);
}
.stage-svg.is-active{ opacity:1; transform:none; }

.stage-svg text{ font-family:var(--mono); }

/* each stage gets its own soft light, placed where that drawing's mass
   is — the four visuals then read as one lit space rather than four
   diagrams on flat black */
.stage-svg[data-stage="0"]{ background:radial-gradient(54% 50% at 62% 50%, rgba(27,143,134,.11), transparent 72%); }
.stage-svg[data-stage="1"]{ background:radial-gradient(50% 62% at 42% 46%, rgba(27,143,134,.10), transparent 74%); }
.stage-svg[data-stage="2"]{ background:radial-gradient(56% 46% at 56% 42%, rgba(27,143,134,.09), transparent 74%); }
.stage-svg[data-stage="3"]{ background:radial-gradient(44% 58% at 50% 50%, rgba(27,143,134,.09), transparent 74%); }

/* shared small parts */
.lbl{ font-size:10px; letter-spacing:.15em; fill:var(--dim); }
.lbl-hi{ fill:var(--acc); }
.box{ fill:rgba(10,17,20,.88); stroke:var(--line-hard); stroke-width:1; }
.box-acc{ fill:rgba(13,30,29,.9); stroke:rgba(62,224,200,.45); }
.wire{ fill:none; stroke:var(--line-hard); stroke-width:1; }
.wire-acc{ stroke:rgba(62,224,200,.5); }

/* 03-1 ontology — a semantic graph standing in space.
   Depth is written by JS as inline opacity / r / stroke-width, so the
   rules here only set colour and type. Never put fill or stroke on a
   descendant selector in this block (see DECISIONS D-05). */
.onto-src rect{ fill:rgba(10,17,20,.92); stroke:var(--line-hard); stroke-width:1; }
.onto-src text{ font-size:9px; letter-spacing:.14em; fill:var(--dim); text-anchor:middle; }
.onto-src-lbl{ font-size:8px; letter-spacing:.24em; fill:var(--dimmer); }
.onto-feed{ stroke:rgba(160,200,196,.22); stroke-width:1; fill:none; }
.onto-edge{ stroke:var(--acc); fill:none; stroke-linecap:round; }
.onto-edge.spine{ stroke:var(--acc-hi); }
.onto-dot{ fill:rgba(126,244,222,.9); }
.onto-node .core{ fill:rgba(8,20,21,.96); stroke:var(--acc); }
.onto-node .glow{ fill:none; }
.onto-node .cap{
  font-size:8.6px; letter-spacing:.1em; fill:var(--text); text-anchor:middle;
  /* a dark casing so labels stay readable where they cross an edge */
  paint-order:stroke; stroke:rgba(5,9,11,.86); stroke-width:2.6px; stroke-linejoin:round;
}
.onto-node.hub .core{ stroke:var(--acc-hi); }
.onto-node.hub .cap{ font-size:9.6px; fill:#f2fffc; letter-spacing:.13em; }
.onto-inst .core{ fill:rgba(8,18,19,.9); stroke:rgba(62,224,200,.55); }
.onto-plane{ fill:none; stroke:rgba(160,200,196,.035); }
.onto-caption{ font-size:8px; letter-spacing:.22em; fill:var(--dimmer); }

/* 03-2 virtual model — one building, four layers, each carrying its
   own kind of content rather than four identical wireframes */
.vm-plate{ fill:rgba(11,22,24,.42); stroke:rgba(62,224,200,.24); stroke-width:1; }
.vm-plate.lead{ fill:rgba(62,224,200,.055); stroke:rgba(62,224,200,.42); }
.vm-tie{ stroke:rgba(62,224,200,.28); stroke-width:1; fill:none; stroke-dasharray:2 5; }
.vm-name{ font-size:9.5px; letter-spacing:.18em; fill:var(--text); }
.vm-tag{ font-size:8px; letter-spacing:.12em; fill:var(--dimmer); }
.vm-lead{ stroke:rgba(160,200,196,.22); stroke-width:1; fill:none; }
.vm-note{ font-size:8px; letter-spacing:.2em; fill:var(--dimmer); }
/* geometry */
.vm-geo{ fill:rgba(62,224,200,.07); stroke:rgba(62,224,200,.5); stroke-width:1; }
.vm-geo-line{ stroke:rgba(126,244,222,.42); stroke-width:1; fill:none; }
.vm-geo-eq{ fill:rgba(126,244,222,.22); stroke:rgba(126,244,222,.6); stroke-width:.8; }
/* physics: thermal bands + flow */
.vm-flow{ stroke:rgba(126,244,222,.62); stroke-width:1; fill:none; stroke-linecap:round; }
.vm-flow-head{ fill:rgba(126,244,222,.75); }
/* data-driven: signals and a prediction trace */
.vm-sig{ stroke:rgba(126,244,222,.7); stroke-width:1.1; fill:none; stroke-linejoin:round; }
.vm-sig.dim{ stroke:rgba(126,244,222,.3); }
.vm-pred{ stroke:var(--acc-hi); stroke-width:1.1; fill:none; stroke-dasharray:3 3; }
.vm-scatter{ fill:rgba(126,244,222,.5); }
.vm-axis{ stroke:rgba(160,200,196,.16); stroke-width:1; }
/* rule-based: a constraint network */
.vm-rule{ fill:rgba(9,20,21,.92); stroke:rgba(62,224,200,.45); stroke-width:1; }
.vm-rule-link{ stroke:rgba(62,224,200,.4); stroke-width:1; fill:none; }
.vm-rule-t{ font-size:7px; letter-spacing:.08em; fill:var(--acc); text-anchor:middle; }
.vm-bar{ fill:rgba(62,224,200,.3); }

/* 03-3 tokenization */
.tk-doc{ fill:rgba(10,17,20,.92); stroke:var(--line-hard); stroke-width:1; }
.tk-doc.back{ fill:rgba(8,13,16,.8); stroke:rgba(160,200,196,.12); }
.tk-line{ stroke:var(--dimmer); stroke-width:1.4; }
.tk-chunk{ fill:rgba(62,224,200,.12); stroke:rgba(62,224,200,.45); stroke-width:.8; }
.tk-chunk.hot{ fill:rgba(62,224,200,.3); stroke:var(--acc-hi); }
.tk-vec{ fill:var(--acc); }
.tk-db{ fill:rgba(6,14,16,.5); stroke:rgba(62,224,200,.34); stroke-width:1; }
.tk-db-grid{ stroke:rgba(160,200,196,.07); stroke-width:1; fill:none; }
.tk-arrow{ stroke:rgba(62,224,200,.45); stroke-width:1; fill:none; }
.tk-hull{ fill:none; stroke:rgba(126,244,222,.32); stroke-width:1; stroke-dasharray:3 4; }

/* 03-4 fine tuning */
.ft-node rect{ fill:rgba(10,17,20,.92); stroke:var(--line-hard); stroke-width:1; }
.ft-node.on rect{ stroke:rgba(62,224,200,.55); fill:rgba(13,30,29,.92); }
.ft-node text{ font-size:9.5px; letter-spacing:.14em; fill:var(--body); text-anchor:middle; }
.ft-node.on text{ fill:var(--text); }
.ft-sub{ font-size:7.5px; letter-spacing:.14em; fill:var(--dimmer); text-anchor:middle; }
.ft-link{ stroke:rgba(62,224,200,.4); stroke-width:1; fill:none; }
.ft-dots circle{ fill:var(--acc-hi); }
.ft-shade{ fill:rgba(62,224,200,.05); stroke:none; }

/* ═══ SCENE 04 — MAIN SERVICES ═══════════════════════════════ */
.svc-svg text{ font-family:var(--mono); }

.svc-rail{ fill:none; stroke:var(--line); stroke-width:1.2; }
.svc-rail-live{
  fill:none; stroke:var(--acc); stroke-width:1.6;
  stroke-linecap:round;
  transition:stroke-dashoffset .55s var(--ease);
  filter:drop-shadow(0 0 6px rgba(62,224,200,.45));
}
.svc-stop circle.ring{ fill:var(--bg); stroke:var(--line-hard); stroke-width:1.2; transition:stroke .45s var(--ease); }
.svc-stop circle.dot{ fill:var(--dimmer); transition:fill .45s var(--ease), r .45s var(--ease); }
.svc-stop text{ font-size:9.5px; letter-spacing:.15em; fill:var(--dimmer); transition:fill .45s var(--ease); }
.svc-stop.done circle.ring{ stroke:rgba(62,224,200,.45); }
.svc-stop.done circle.dot{ fill:var(--acc-deep); }
.svc-stop.done text{ fill:var(--dim); }
.svc-stop.on circle.ring{ stroke:var(--acc); }
.svc-stop.on circle.dot{ fill:var(--acc-hi); r:6; }
.svc-stop.on text{ fill:var(--text); }
.svc-stop.soon.on circle.ring{ stroke:var(--warm); }
.svc-stop.soon.on circle.dot{ fill:var(--warm); }

.svc-halo{ fill:none; stroke:var(--acc); stroke-width:1; opacity:.35; }

/* the service travelling the rail */
.svc-token{ transition:transform .18s linear; }
.svc-token .tok-halo{ fill:rgba(62,224,200,.18); stroke:var(--acc-hi); stroke-width:1; }
.svc-token .tok-core{ fill:var(--acc-hi); filter:drop-shadow(0 0 6px rgba(126,244,222,.9)); }

/* card swap */
.svc-card{
  opacity:0; transform:translate(0, 12px);
  transition:opacity .45s var(--ease-out), transform .45s var(--ease-out);
}
.svc-card.is-in{ opacity:1; transform:translate(0, 0); }

/* direct child only — a descendant selector here would beat the fill
   presentation attributes on every rect inside the card */
.svc-panel > rect{ fill:rgba(8,14,16,.86); stroke:var(--line); stroke-width:1; }
.svc-panel .ttl{ font-size:10px; letter-spacing:.2em; fill:var(--acc); }
.svc-panel .itm{ font-size:10.5px; letter-spacing:.06em; fill:var(--body); }
.svc-panel .sub{ font-size:9px; letter-spacing:.12em; fill:var(--dimmer); }

/* ═══ SCENE 05 — RESOURCES ═══════════════════════════════════ */
.res{
  padding:clamp(90px,13vw,170px) 0;
  background:
    radial-gradient(64% 46% at 16% 4%, rgba(27,143,134,.09), transparent 68%),
    var(--bg-1);
  border-block:1px solid var(--line-soft);
}
.res-stage{
  margin-top:clamp(24px,4vw,44px);
  border:1px solid var(--line-soft); border-radius:14px;
  background:
    radial-gradient(60% 70% at 26% 50%, rgba(27,143,134,.10), transparent 68%),
    var(--bg-2);
  padding:clamp(10px,2vw,20px);
  overflow:hidden;
}
.res-svg{ width:100%; height:auto; }
.res-svg text{ font-family:var(--mono); }

.res-chip .bg{ fill:rgba(10,20,22,.94); stroke:var(--line-hard); stroke-width:1; transition:stroke .5s var(--ease), fill .5s var(--ease); }
.res-chip.picked .bg{ stroke:var(--acc); fill:rgba(14,36,34,.96); }
.res-chip .nm{ font-size:11px; letter-spacing:.12em; fill:var(--body); text-anchor:middle; transition:fill .5s var(--ease); }
.res-chip.picked .nm{ fill:var(--text); }
.res-chip .dt{ fill:var(--dimmer); transition:fill .5s var(--ease); }
.res-chip.picked .dt{ fill:var(--acc); }

.res-link{
  fill:none; stroke:var(--acc); stroke-width:1; opacity:0;
  transition:opacity .5s var(--ease);
}
.res-link.on{ opacity:.42; }

.res-svc rect{ fill:rgba(13,30,29,.9); stroke:var(--acc); stroke-width:1.2; }
.res-svc .t1{ font-size:12px; letter-spacing:.18em; fill:var(--text); text-anchor:middle; }
.res-svc .t2{ font-size:9px; letter-spacing:.2em; fill:var(--acc); text-anchor:middle; }
.res-pool-label{ font-size:10px; letter-spacing:.24em; fill:var(--dimmer); }
.res-sub{ font-size:8px; letter-spacing:.18em; fill:var(--dimmer); }

.res-list{
  margin-top:clamp(28px,4vw,44px);
  display:grid; grid-template-columns:repeat(3,minmax(0,1fr));
  gap:1px; background:var(--line-soft);
  border:1px solid var(--line-soft);
}
.res-list li{
  background:var(--bg-1); padding:22px 20px;
  display:flex; flex-direction:column; gap:7px;
}
.res-list b{
  font-family:var(--mono); font-size:11px; letter-spacing:.18em;
  text-transform:uppercase; color:var(--acc); font-weight:500;
}
.res-list span{ font-size:13.5px; line-height:1.6; color:var(--dim); }

/* ═══ SCENE 06 — APG ═════════════════════════════════════════ */
.apg{ padding:clamp(90px,13vw,170px) 0; position:relative; overflow:hidden; }
.apg::before{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(60% 45% at 78% 22%, rgba(27,143,134,.11), transparent 70%);
}
.apg .wrap{ position:relative; }

.apg-split{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.04fr);
  gap:clamp(32px,4vw,64px); align-items:start;
}
/* the diagram is taller than the viewport at desktop widths, so pinning
   it would cut off the application row — let it scroll with the copy */
.apg-visual{ align-self:start; }
.apg-svg{ width:100%; height:auto; }
.apg-svg text{ font-family:var(--mono); }

/* the APG name leads the section; the contribution is the line under it */
.apg-name{ letter-spacing:-.028em; }
.apg-name .apg-abbr{ color:var(--acc); font-weight:600; white-space:nowrap; }
.apg-headline{
  margin-top:14px;
  font-size:clamp(17px,2.1vw,26px); line-height:1.4; font-weight:500;
  letter-spacing:.004em; color:var(--acc-hi);
}
html[data-lang="ko"] .apg-headline{ letter-spacing:-.014em; line-height:1.44; }

/* the scope line: what kind of thing APG is, before the explanation */
.apg-scope{
  margin-top:12px; padding-top:12px;
  border-top:1px solid var(--line-soft);
  display:inline-block;
  font-family:var(--mono); font-size:11px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--dim);
}
html[data-lang="ko"] .apg-scope{ letter-spacing:.06em; text-transform:none; font-size:12px; }

/* One narrative column: the coupling problem, then what APG does about
   it. A two-column version read like a journal abstract rather than a
   project page.
   The measure runs close to the full rail (1180px less 2×64px of pad =
   1052px of content) on purpose: capped at 74ch the lede stopped short
   of two-thirds of the column and read as the surviving half of a
   two-column layout. Longer lines are paid for with larger type and
   more leading, so it sets as a lede rather than as body copy. */
.apg-lede{
  margin-top:clamp(24px,2.8vw,34px);
  max-width:min(1040px, 100%);
}
.apg-lede p{
  font-size:clamp(15px,1.45vw,18.5px); line-height:1.8; color:var(--body);
  text-wrap:pretty;
}
.apg-lede p + p{ margin-top:clamp(16px,1.8vw,24px); }
.apg-lede p b{ color:var(--text); font-weight:600; }
html[data-lang="ko"] .apg-lede{ max-width:min(980px, 100%); }
html[data-lang="ko"] .apg-lede p{ line-height:1.9; }

/* ── the pipeline ──
   Every label lives on its own baseline inside its own box, and the
   phase names are set horizontally above each group. The previous
   version rotated them into a 62-unit bracket and set two labels on
   one baseline, which collided at every viewport width. */
.apg-stage-bg{ stroke:none; }
.apg-phase-box{ fill:none; stroke:rgba(160,200,196,.13); stroke-width:1; }
.apg-phase-lbl{ font-size:9px; letter-spacing:.18em; fill:var(--acc); opacity:.8; }
.apg-phase-ix{ font-size:8.6px; letter-spacing:.16em; fill:var(--dimmer); }

.apg-step .bg{ fill:rgba(9,16,18,.94); stroke:var(--line-hard); stroke-width:1; }
.apg-step.key .bg{ stroke:rgba(62,224,200,.48); fill:rgba(12,28,27,.95); }
.apg-step .nm{ font-size:11.5px; letter-spacing:.03em; fill:var(--text); }
.apg-step .sb{ font-size:8.6px; letter-spacing:.06em; fill:var(--dim); }
.apg-step .ix{ font-size:9px; letter-spacing:.16em; fill:var(--acc); }

.apg-conn{ fill:none; stroke:rgba(62,224,200,.42); stroke-width:1; }
.apg-conn.soft{ stroke:rgba(160,200,196,.22); }
.apg-flow-lbl{ font-size:8.4px; letter-spacing:.12em; fill:var(--dim); }
.apg-spark{ fill:var(--acc-hi); }
.apg-spark.warm{ fill:#dff6f1; }

/* Process Library — a repository, not a box: finalized processes stack
   up in it and are provisioned out of it */
.apg-lib .shelf{ fill:rgba(11,26,26,.95); stroke:rgba(62,224,200,.58); stroke-width:1; }
.apg-lib .nm{ font-size:10.5px; letter-spacing:.18em; fill:var(--acc-hi); }
.apg-lib .sub{ font-size:8.2px; letter-spacing:.06em; fill:var(--dim); }
.apg-card{ fill:rgba(62,224,200,.11); stroke:rgba(126,244,222,.5); stroke-width:.9; }
.apg-card.fresh{ fill:rgba(62,224,200,.26); stroke:var(--acc-hi); }
.apg-card-line{ stroke:rgba(126,244,222,.5); stroke-width:.8; fill:none; }

.apg-io .bg{ fill:rgba(9,16,18,.94); stroke:var(--line-hard); stroke-width:1; }
.apg-io.key .bg{ stroke:rgba(62,224,200,.42); fill:rgba(12,28,27,.95); }
.apg-io .nm{ font-size:10px; letter-spacing:.16em; fill:var(--text); }
.apg-io.key .nm{ fill:var(--text); }
.apg-io .sub{ font-size:8.2px; letter-spacing:.06em; fill:var(--dimmer); }

.apg-app .bg{ fill:rgba(9,16,18,.94); stroke:rgba(160,200,196,.28); stroke-width:1; }
.apg-app .nm{ font-size:8.6px; letter-spacing:.1em; fill:var(--body); }
.apg-app .rep{ font-size:8px; letter-spacing:.1em; fill:var(--acc); opacity:.75; }

.apg-divider{ stroke:rgba(62,224,200,.36); stroke-width:1; stroke-dasharray:4 5; }
.apg-side{ font-size:8.8px; letter-spacing:.16em; fill:var(--acc); opacity:.8; }

.apg-body{ display:flex; flex-direction:column; gap:clamp(26px,3.4vw,40px); }
.apg-point{ position:relative; padding-left:52px; }
.ap-n{
  position:absolute; left:0; top:2px;
  font-family:var(--mono); font-size:11px; letter-spacing:.16em; color:var(--acc);
  width:34px; padding-top:5px; border-top:1px solid var(--acc-dark);
}
.apg-point h3{
  font-size:clamp(17px,1.7vw,21px); font-weight:600; color:var(--text);
  letter-spacing:-.01em; margin-bottom:10px;
}
.apg-point p{ font-size:15px; line-height:1.76; color:var(--body); }
html[data-lang="ko"] .apg-point h3{ line-height:1.42; }
html[data-lang="ko"] .apg-point p{ line-height:1.86; }

/* ── publication card ──────────────────────────────────────────
   A compact horizontal citation object: the source on the left in a
   narrow metadata column, the paper itself on the right. The previous
   stacked version wrapped the title over three lines and left a large
   empty gutter on the right. */
.pub{
  display:grid; grid-template-columns:minmax(0,23%) minmax(0,1fr);
  gap:clamp(22px,3vw,44px);
  margin-top:clamp(44px,6vw,76px);
  padding:clamp(22px,2.8vw,32px) clamp(24px,3vw,36px);
  border:1px solid var(--line-hard); border-radius:14px;
  background:
    radial-gradient(120% 160% at 100% 0%, rgba(62,224,200,.075), transparent 56%),
    linear-gradient(108deg, rgba(13,30,29,.56), rgba(9,15,18,.5));
  text-decoration:none; position:relative; overflow:hidden;
  transition:border-color .3s var(--ease), transform .3s var(--ease), box-shadow .3s var(--ease);
}
.pub::before{
  content:""; position:absolute; inset:0 auto 0 0; width:2px;
  background:linear-gradient(180deg, var(--acc), rgba(62,224,200,.12));
}
.pub:hover{
  border-color:rgba(62,224,200,.55); transform:translateY(-2px);
  box-shadow:0 22px 56px -34px rgba(62,224,200,.45);
}

.pub-source{
  display:flex; flex-direction:column; gap:9px;
  border-right:1px solid var(--line-soft); padding-right:clamp(16px,2vw,28px);
}
.pub-kicker{
  align-self:flex-start;
  font-family:var(--mono); font-size:9.5px; letter-spacing:.2em;
  text-transform:uppercase; color:var(--acc);
  padding:4px 9px; border:1px solid rgba(62,224,200,.28); border-radius:100px;
  background:rgba(62,224,200,.05);
}
.pub-journal{
  font-size:13.5px; font-weight:600; line-height:1.36; letter-spacing:-.008em;
  color:var(--text);
}
.pub-meta{ margin:4px 0 0; display:grid; gap:5px; }
.pub-meta > div{ display:flex; align-items:baseline; gap:8px; }
.pub-meta dt{
  font-family:var(--mono); font-size:9px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--dimmer); min-width:4.6em;
}
.pub-meta dd{
  margin:0; font-family:var(--mono); font-size:11.5px; letter-spacing:.03em;
  color:var(--body); font-variant-numeric:tabular-nums;
}

.pub-body{ display:flex; flex-direction:column; }
.pub-title{
  font-size:clamp(18px,2.05vw,26px); line-height:1.30; letter-spacing:-.018em;
  font-weight:600; color:var(--text); text-wrap:balance;
  /* tuned so the title balances onto two lines at desktop widths */
  max-width:46ch;
}
.pub-authors{
  margin-top:clamp(12px,1.5vw,16px);
  font-size:13.5px; line-height:1.6; color:var(--body);
}
.pub-authors sup{ color:var(--acc); font-size:.85em; }
.pub-corr{ margin-left:10px; font-size:11px; color:var(--dimmer); white-space:nowrap; }
.pub-line{
  margin-top:auto; padding-top:clamp(16px,2vw,22px);
  display:flex; align-items:baseline; justify-content:space-between;
  gap:14px 26px; flex-wrap:wrap;
}
.pub-doi{
  font-family:var(--mono); font-size:11.5px; letter-spacing:.02em; color:var(--dim);
  overflow-wrap:anywhere;
}
.pub-go{
  display:inline-flex; align-items:center; gap:8px;
  font-size:13.5px; font-weight:600; color:var(--acc); white-space:nowrap;
}
.pub-go svg{ width:13px; height:13px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; transition:transform .25s var(--ease); }
.pub:hover .pub-go svg{ transform:translate(3px,-3px); }

/* ═══ SCENE 07 — IMPACT ══════════════════════════════════════
   The chart carries the argument (without → with → preserved) and the
   0.9 TWh block carries the result. The 75% figure is an assumption, so
   it is labelled as one inside the chart header rather than set as a
   headline number competing with the result. */
.impact{
  padding:clamp(90px,13vw,170px) 0;
  background:
    radial-gradient(70% 50% at 84% 4%, rgba(27,143,134,.10), transparent 66%),
    var(--bg-1);
  border-block:1px solid var(--line-soft);
}

.impact-compare{
  margin-top:clamp(34px,5vw,58px);
  border:1px solid var(--line-soft); border-radius:16px;
  background:linear-gradient(180deg, rgba(13,21,25,.7), rgba(8,13,16,.55));
  padding:clamp(22px,3.2vw,40px);
}
.ic-top{
  display:flex; align-items:flex-start; justify-content:space-between;
  gap:18px 28px; flex-wrap:wrap; margin-bottom:clamp(28px,3.6vw,42px);
}
.ic-title{
  font-size:clamp(15px,1.6vw,19px); font-weight:600; letter-spacing:-.012em;
  color:var(--text);
}
.ic-scope{
  margin-top:7px;
  font-family:var(--mono); font-size:11px; letter-spacing:.1em;
  color:var(--dim);
}
html[data-lang="ko"] .ic-scope{ letter-spacing:.05em; font-size:11.5px; }

/* the assumption, marked as an assumption */
.ic-assume{
  display:flex; align-items:baseline; gap:9px; flex-wrap:wrap;
  padding:9px 15px; border-radius:100px;
  border:1px solid rgba(240,180,90,.28); background:rgba(240,180,90,.06);
}
.ica-k{
  font-family:var(--mono); font-size:9.5px; letter-spacing:.2em;
  text-transform:uppercase; color:var(--warm);
}
.ica-v{
  font-family:var(--mono); font-size:17px; letter-spacing:-.01em;
  color:var(--warm); font-variant-numeric:tabular-nums; font-weight:600;
}
.ica-l{ font-size:12.5px; color:var(--dim); }

/* one plot, one scale */
.ic-plot{ position:relative; }
.ic-grid{ position:absolute; inset:0 0 32px 0; pointer-events:none; }
.ic-grid span{
  position:absolute; top:0; bottom:0; left:var(--t);
  width:1px; background:rgba(160,200,196,.08);
}
.ic-grid span:first-child,
.ic-grid span:last-child{ background:rgba(160,200,196,.15); }

.ic-row{
  position:relative;
  display:grid; grid-template-columns:minmax(0,1fr) auto;
  align-items:baseline; gap:8px 18px;
  padding-bottom:clamp(24px,3vw,34px);
}
.ic-scn{
  font-family:var(--mono); font-size:10.5px; letter-spacing:.2em;
  text-transform:uppercase; color:var(--dim);
}
html[data-lang="ko"] .ic-scn{ letter-spacing:.06em; text-transform:none; font-size:12px; }
.ic-total{
  font-family:var(--mono); font-size:clamp(18px,2.3vw,28px); letter-spacing:-.012em;
  color:var(--text); font-variant-numeric:tabular-nums; white-space:nowrap;
}
.ic-total em{
  font-style:normal; font-size:10.5px; letter-spacing:.16em; text-transform:uppercase;
  color:var(--dimmer); margin-right:.8em;
}
html[data-lang="ko"] .ic-total em{ letter-spacing:.04em; text-transform:none; font-size:11.5px; }

/* one bar per scenario, split at the point where APG's share ends —
   so 795 = 199 + 596 is visible as a split, not inferred from three
   separate bars */
.ic-track{
  grid-column:1 / -1; position:relative; margin-top:4px;
  height:26px; border-radius:5px;
  background:rgba(255,255,255,.022);
  box-shadow:inset 0 0 0 1px rgba(160,200,196,.05);
}
.ic-seg{
  position:absolute; top:0; bottom:0;
  left:var(--a); right:calc(100% - var(--b));
  display:flex; align-items:center; justify-content:center;
  transform:scaleX(0); transform-origin:left;
  transition:transform .95s var(--ease-out) var(--bd,0s);
}
.ic-seg b{
  font-family:var(--mono); font-size:11px; letter-spacing:.04em; font-weight:500;
  font-variant-numeric:tabular-nums;
  opacity:0; transition:opacity .5s var(--ease) calc(var(--bd,0s) + .5s);
}
.impact-compare.is-in .ic-seg{ transform:scaleX(1); }
.impact-compare.is-in .ic-seg b{ opacity:1; }

.ic-seg.keep{
  border-radius:5px 0 0 5px;
  background:linear-gradient(180deg, rgba(160,200,196,.20), rgba(160,200,196,.11));
  box-shadow:inset 0 0 0 1px rgba(160,200,196,.16);
}
.ic-seg.keep b{ color:var(--body); }
.ic-seg.save{
  border-radius:0 5px 5px 0;
  background:
    repeating-linear-gradient(118deg, rgba(255,255,255,.07) 0 6px, rgba(255,255,255,0) 6px 13px),
    linear-gradient(180deg, var(--acc-hi), var(--acc) 62%, #23a596);
  box-shadow:inset 0 0 0 1px rgba(126,244,222,.5), 0 0 22px -6px rgba(62,224,200,.5);
}
.ic-seg.save b{ color:#04201d; }
.ic-row:nth-child(2) .ic-seg{ --bd:.12s; }
.ic-row:nth-child(3) .ic-seg{ --bd:.42s; }

/* segment key */
.ic-key{
  display:flex; gap:12px 26px; flex-wrap:wrap;
  margin:0 0 clamp(18px,2.4vw,26px);
}
.ic-key li{
  display:flex; align-items:center; gap:9px;
  font-size:12.5px; color:var(--dim);
}
.ick{ width:16px; height:10px; border-radius:2px; flex:none; }
.ick-keep{
  background:linear-gradient(180deg, rgba(160,200,196,.20), rgba(160,200,196,.11));
  box-shadow:inset 0 0 0 1px rgba(160,200,196,.16);
}
.ick-save{
  background:linear-gradient(180deg, var(--acc-hi), var(--acc) 62%, #23a596);
  box-shadow:inset 0 0 0 1px rgba(126,244,222,.5);
}

.ic-axis{
  position:relative; height:30px; margin-top:2px;
  border-top:1px solid var(--line-soft);
}
.ic-axis span{
  position:absolute; top:9px; left:var(--t); transform:translateX(-50%);
  font-family:var(--mono); font-size:9.5px; letter-spacing:.12em;
  color:var(--dimmer); font-variant-numeric:tabular-nums; white-space:nowrap;
}
.ic-axis span:first-child{ transform:none; }
.ic-axis span:last-child{ transform:translateX(-100%); }

.ic-note{
  margin-top:clamp(18px,2.4vw,26px);
  font-size:12.5px; line-height:1.7; color:var(--dimmer); max-width:74ch;
}

/* ── the result ───────────────────────────────────────────────
   Tied visually to the chart above by a short vertical rule, so the
   number reads as the conclusion of row 03 rather than a new claim. */
.impact-grand{
  position:relative;
  margin-top:clamp(56px,7vw,92px); text-align:center;
  padding:clamp(44px,6vw,76px) clamp(20px,3vw,40px) clamp(36px,5vw,58px);
  border:1px solid rgba(62,224,200,.26); border-radius:20px;
  background:
    radial-gradient(60% 100% at 50% 0%, rgba(62,224,200,.14), transparent 68%),
    radial-gradient(90% 120% at 50% 120%, rgba(27,143,134,.10), transparent 70%),
    rgba(7,14,16,.5);
  overflow:hidden;
}
.impact-grand::before{
  content:""; position:absolute; inset:0 0 auto 0; height:1px;
  background:linear-gradient(90deg, transparent, var(--acc), transparent);
  opacity:.7;
}
.ig-tie{
  position:absolute; left:50%; top:calc(-1 * clamp(56px,7vw,92px)); width:1px;
  height:clamp(56px,7vw,92px);
  background:linear-gradient(180deg, transparent, rgba(62,224,200,.55));
}
.ig-kicker{
  font-family:var(--mono); font-size:11px; letter-spacing:.3em;
  text-transform:uppercase; color:var(--acc); margin-bottom:clamp(12px,1.6vw,18px);
}
.ig-num{
  font-size:clamp(64px,13vw,168px); line-height:.92; letter-spacing:-.055em; font-weight:650;
  font-variant-numeric:tabular-nums;
  background:linear-gradient(168deg, #ffffff 0%, var(--acc-hi) 34%, var(--acc) 72%, #2f9c90 100%);
  -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent;
  color:var(--acc-hi);
  filter:drop-shadow(0 0 44px rgba(62,224,200,.24));
}
/* same guard as the hero title: an unsupported background-clip would
   make the page's headline result number invisible */
@supports not ((-webkit-background-clip:text) or (background-clip:text)){
  .ig-num{ background:none; -webkit-text-fill-color:var(--acc-hi); color:var(--acc-hi); }
}
.ig-num em{
  display:block; margin-top:clamp(14px,2vw,22px);
  font-style:normal; font-family:var(--mono); font-weight:400;
  font-size:clamp(12px,1.5vw,17px); letter-spacing:.24em;
  background:none; -webkit-text-fill-color:initial; color:var(--acc);
  filter:none;
}
.ig-lead{
  margin-top:clamp(20px,2.6vw,30px);
  font-size:clamp(15px,1.7vw,20px); line-height:1.6; color:var(--text);
  max-width:40ch; margin-inline:auto; letter-spacing:-.01em;
}
html[data-lang="ko"] .ig-lead{ line-height:1.7; }
.ig-link{
  margin-top:13px;
  font-family:var(--mono); font-size:11.5px; letter-spacing:.06em;
  color:var(--dim);
}
html[data-lang="ko"] .ig-link{ letter-spacing:.03em; font-size:12px; }

.disclaimer{
  margin-top:clamp(34px,4.2vw,52px);
  padding:20px 22px; border-left:2px solid rgba(240,180,90,.5);
  background:rgba(240,180,90,.035);
  border-radius:0 8px 8px 0;
}
.disclaimer p{ font-size:12.5px; line-height:1.75; color:var(--dimmer); max-width:92ch; }
.disclaimer b{ color:rgba(240,180,90,.9); font-weight:600; }

/* ═══ SCENE 08 — CLOSING ═════════════════════════════════════ */
.closing{
  position:relative; overflow:hidden;
  min-height:92vh; min-height:92svh; display:flex; align-items:center;
  padding:clamp(90px,13vw,160px) 0;
}
.closing-canvas{ position:absolute; inset:0; width:100%; height:100%; }
.closing::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(70% 60% at 50% 50%, transparent 20%, rgba(5,8,10,.6) 78%, var(--bg) 100%);
}
.closing-inner{ position:relative; z-index:2; text-align:center; }
.closing-title{
  font-size:clamp(31px,5.4vw,74px); line-height:1.10; letter-spacing:-.032em;
  font-weight:650; color:var(--text); text-wrap:balance;
  max-width:24ch; margin-inline:auto;
}
html[data-lang="ko"] .closing-title{ line-height:1.24; letter-spacing:-.04em; max-width:18ch; }
.closing-sub{
  margin-top:clamp(20px,2.6vw,30px);
  font-family:var(--mono); font-size:clamp(11.5px,1.35vw,15px);
  letter-spacing:.16em; text-transform:uppercase; color:var(--acc);
}
.closing-cta{
  margin-top:clamp(36px,4.6vw,56px);
  display:flex; align-items:center; justify-content:center; gap:14px; flex-wrap:wrap;
}
.closing-note{
  margin-top:20px;
  font-family:var(--mono); font-size:11px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--dimmer);
}

/* ═══ RESPONSIVE ═════════════════════════════════════════════ */
@media (max-width:1024px){
  .apg-split{ grid-template-columns:1fr; gap:44px; }
  .apg-visual{ max-width:470px; margin-inline:auto; }
  .res-list{ grid-template-columns:repeat(2,minmax(0,1fr)); }
}

@media (max-width:960px){
  /* sticky visual moves above the copy, at reduced height */
  .scene-grid{ grid-template-columns:1fr; gap:0; }
  .scene-visual{
    top:var(--bar-h);
    height:auto; padding:14px 0 42px;
    /* opaque almost all the way down: the caption sits in this band and the
       copy scrolls underneath, so a transparent tail puts text over text */
    background:linear-gradient(180deg, var(--bg) 0%, var(--bg) 92%, rgba(5,8,10,0) 100%);
    z-index:5;
  }
  .visual-frame{ aspect-ratio:1/1; max-height:44vh; width:min(100%,44vh); max-height:44svh; width:min(100%,44svh); }
  .visual-caption{ bottom:-26px; left:50%; transform:translateX(-50%); white-space:nowrap; }
  .scene-copy{ padding:0 0 clamp(40px,8vh,80px); }
  .step{ min-height:auto; padding:34px 0; border-top:1px solid var(--line-soft); opacity:1; filter:none; }
  .step:first-child{ border-top:0; }
  .scene-copy .sec-head{ padding-top:30px; margin-bottom:20px; }
}

@media (max-width:560px){
  .res-list{ grid-template-columns:1fr; }
  .visual-frame{ max-height:38vh; width:min(100%,38vh); max-height:38svh; width:min(100%,38svh); }
  .step-flow b{ font-size:10px; padding:5px 9px; }
  .ic-row{ grid-template-columns:1fr; }
  .ic-total{ font-size:20px; }
  .ic-track{ height:22px; }
  .ic-seg b{ font-size:10px; }
  .ic-axis span:nth-child(2),
  .ic-axis span:nth-child(4){ display:none; }
}

@media (prefers-reduced-motion:reduce){
  .step{ opacity:1 !important; filter:none !important; }
  .stage-svg{ transition:none; }
  .svc-card{ opacity:1 !important; transform:none !important; }
  .svc-token{ transition:none; }
  /* the bands must still be at full length, not stuck at scaleX(0) */
  /* segments must still be at full length, not stuck at scaleX(0) */
  .ic-seg{ transform:scaleX(1) !important; }
  .ic-seg b{ opacity:1 !important; }
}

/* ═══ SCENE 06 — APG body parts ═════════════════════════════════
   The pipeline's own SVG styles live further up. Steps, phases and the
   Process Library follow the APG paper (Fig. 2 / Table 1).
   See 00_인수인계/DECISIONS.md D-11 and D-16. */
.apg-why-kicker{
  font-family:var(--mono); font-size:10px; letter-spacing:.24em;
  text-transform:uppercase; color:var(--acc); margin-bottom:-8px;
}

/* ── evidence strip: the paper's measured result, with its conditions ── */
.apg-evidence{
  margin-top:clamp(40px,5vw,64px);
  border:1px solid var(--line); border-radius:12px;
  background:linear-gradient(180deg, rgba(13,21,25,.75), rgba(7,12,15,.6));
  padding:clamp(24px,3vw,34px) clamp(22px,3vw,36px);
}
.ae-kicker{
  font-family:var(--mono); font-size:9.5px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--dim); line-height:1.7;
}
.ae-grid{
  list-style:none; margin:22px 0 0;
  display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(18px,2.4vw,32px);
}
.ae-grid li{
  display:flex; flex-direction:column; gap:4px;
  border-left:1px solid var(--line); padding-left:18px;
}
.ae-up{ font-family:var(--mono); font-size:9.5px; letter-spacing:.2em; color:var(--dimmer); text-transform:uppercase; }
.ae-num{
  font-size:clamp(30px,3.6vw,46px); font-weight:600; letter-spacing:-.03em;
  color:var(--acc); line-height:1.06;
}
/* the figure counts up from 0.0, so it changes digit count mid-flight —
   a fixed tabular box keeps the % sign from sliding */
.ae-num > span{
  display:inline-block; min-width:4ch; text-align:left;
  font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1;
}
.ae-num em{ font-style:normal; font-size:.5em; margin-left:2px; }
.ae-lab{ font-size:13px; color:var(--body); }
.ae-foot{
  margin-top:22px; padding-top:16px; border-top:1px solid var(--line-soft);
  font-size:13px; line-height:1.7; color:var(--dim);
}
/* the bridge into Impact is meant to breathe over two lines — the
   measure is set so both languages break evenly rather than dropping a
   short tail, and balance keeps the two lines close in length */
.apg-bridge{
  margin-top:clamp(30px,4vw,46px);
  font-size:clamp(17px,1.9vw,23px); line-height:1.56; color:var(--text);
  letter-spacing:-.015em; max-width:min(880px, 100%);
  text-wrap:balance;
}
html[data-lang="ko"] .apg-bridge{ max-width:min(760px, 100%); line-height:1.62; }

@media (max-width:860px){
  .ae-grid{ grid-template-columns:1fr; gap:18px; }
  .pub{ grid-template-columns:1fr; gap:20px; }
  .pub-source{ border-right:0; padding-right:0; padding-bottom:18px; border-bottom:1px solid var(--line-soft); }
  .pub-meta{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .pub-title{ max-width:none; }
  .pub-line{ flex-direction:column; align-items:flex-start; gap:10px; }
}
