/* ═══════════════════════════════════════════════════════════════════
   행복한지구 — design layer
   Loaded after style.css on the public pages. The admin never loads it, and
   removing this one <link> restores the original look completely.
   ═══════════════════════════════════════════════════════════════════ */

/* ── the real company logo ──────────────────────────────────────────── */
.brand .bmark{display:block;width:clamp(38px,4vw,46px);height:auto;flex:0 0 auto}
.orb .orb-logo{display:block;width:min(150px,42%);height:auto;margin:0 auto}

/* ── 수상 내역 / 주요 이력 spacing ───────────────────────────────────
   주요 이력 carries eight entries and 수상 내역 two; stretching both columns
   to the taller one left dead space under the awards. */
.lcols{align-items:start;gap:26px 34px}
.lcols li{margin-bottom:2px;line-height:1.65}
.lcols li::before{top:9px;width:5px;height:5px}
.lnote{margin-top:16px}

/* ── event card: the 예정 badge sat on top of the title ────────────── */
.event:has(.e-badge) .e-body h3{padding-right:clamp(62px,8vw,84px)}
@supports not selector(:has(*)){ .e-body h3{padding-right:clamp(62px,8vw,84px)} }

/* ── 출판 분류 spacing ──────────────────────────────────────────────── */
.pub-group + .pub-group{margin-top:clamp(26px,3.2vw,42px)}
.pub-group-head{margin:0 0 clamp(14px,1.8vw,20px)}
.pub-group-head::after{margin-top:12px}
.pub-group-head p{margin-top:6px}

/* ── smoother scrolling ─────────────────────────────────────────────
   A blurred backdrop on a fixed element must be re-read and re-rasterised
   every frame of a scroll. The bar keeps its translucency without it. */
.head{backdrop-filter:none!important;-webkit-backdrop-filter:none!important}
.sky{will-change:transform}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){ html{scroll-behavior:auto} }


/* ═══════════════════════════════════════════════════════════════════
   HOME HERO — built to the supplied mock-up
   Navy sky with one green bloom top-left, a floating rounded nav bar, copy
   on the left, a lit globe inside a thin orbital ring on the right, and
   leaves drifting through in front and behind.
   ═══════════════════════════════════════════════════════════════════ */

:root{
  --hx-green:#6EE787;
  --hx-green-2:#3FCF6A;
  --hx-navy-0:#050D1A;
  --hx-navy-1:#0A1729;
  --hx-navy-2:#0E2036;
  --leaf:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M88 12C56 14 30 26 18 46 8 62 12 80 24 88c14 9 36 3 52-14 14-15 16-42 12-62Z'/%3E%3C/svg%3E");
}

/* the sky: navy with a single green bloom — no nebula, no violet */
:root[data-theme="night"]{
  /* blues taken down 10%, every hue a little more saturated */
  --bg-0:#061422; --bg-1:#0A1E33; --bg-2:#040F1B;
  --sky:
    /* the green bloom, upper left */
    radial-gradient(48% 42% at 6% 10%,rgba(32,164,96,.50) 0%,transparent 64%),
    /* the lit blue field the globe sits in */
    radial-gradient(64% 58% at 72% 38%,rgba(18,84,160,.66) 0%,transparent 68%),
    radial-gradient(46% 40% at 88% 20%,rgba(24,98,164,.38) 0%,transparent 66%),
    /* deep water at the foot of the page */
    radial-gradient(96% 56% at 46% 112%,rgba(5,21,47,.88) 0%,transparent 62%),
    linear-gradient(178deg,#061422 0%,#0A1E33 48%,#08182C 100%);
  --sky-op:.16;
  --brand:#6EE787; --brand-2:#A8F3B8;
}

/* ── navigation: one floating rounded bar ───────────────────────── */
/* Frosted glass. This is the one place a backdrop blur earns its cost: it is
   a small fixed strip rather than a full-page layer, and it is what makes the
   bar read as glass instead of a painted panel. */
/* The bar itself carries NO backdrop-filter: like transform, a backdrop
   filter makes the element a containing block for position:fixed children,
   and the mobile menu is exactly that — it was opening inside the 64px bar
   instead of over the page. The glass lives on ::after instead, which is not
   an ancestor of the drawer. */
.head{position:fixed;top:14px;left:0;right:0;margin-inline:auto;
  width:min(1640px,calc(100% - 26px));padding:15px 20px 15px 22px;
  border-radius:18px;background:transparent;border:0;box-shadow:none;
  backdrop-filter:none!important;-webkit-backdrop-filter:none!important}
.head::after{content:"";position:absolute;inset:0;z-index:-1;opacity:1;
  border-radius:inherit;
  backdrop-filter:blur(22px) saturate(1.6);
  -webkit-backdrop-filter:blur(22px) saturate(1.6);
  border:1px solid rgba(255,255,255,.14);
  background:linear-gradient(180deg,rgba(20,40,64,.58),rgba(10,24,42,.48));
  box-shadow:0 16px 44px -18px rgba(0,0,0,.66),inset 0 1px 0 rgba(255,255,255,.10);
  transition:background .55s var(--e-soft),border-color .55s var(--e-soft)}
:root[data-theme="day"] .head::after{
  border-color:rgba(255,255,255,.72);
  background:linear-gradient(180deg,rgba(255,255,255,.68),rgba(255,255,255,.48));
  box-shadow:0 14px 38px -18px rgba(30,80,120,.34),inset 0 1px 0 rgba(255,255,255,.9)}
.head .brand b{font-size:1.12rem;letter-spacing:-.02em}
.head .brand i{font-size:.6rem;letter-spacing:.2em;opacity:.72}

/* style.css pushes .nav right with margin-left:auto, which left a wide gap
   after the logo. Auto margins on both sides centre it in the bar instead. */
.nav{background:none;border:0;padding:0;gap:6px;box-shadow:none;
  margin-left:auto;margin-right:auto}
.nav a{position:relative;padding:10px 16px;border-radius:0;font-weight:500;
  font-size:1.02rem;letter-spacing:-.01em;color:rgba(228,238,248,.86)}
:root[data-theme="day"] .nav a{color:var(--ink-2)}
.nav a::before{display:none}
.nav a::after{content:"";position:absolute;left:50%;bottom:0;width:0;height:2px;
  border-radius:2px;background:#6EE787;opacity:1;transform:translateX(-50%);
  transition:width .28s var(--e-out)}
.nav a:hover{color:#fff;transform:none}
:root[data-theme="day"] .nav a:hover{color:var(--ink)}
.nav a[aria-current="page"]{color:#6EE787;font-weight:600}
.nav a[aria-current="page"]::after{width:26px}
.nav a.out{color:#6EE787}
:root[data-theme="day"] .nav a[aria-current="page"],
:root[data-theme="day"] .nav a.out{color:#1E8B4A}
:root[data-theme="day"] .nav a[aria-current="page"]::after{background:#1E8B4A}

/* the theme switch becomes a plain circular button */
.tgl{width:42px;height:42px;padding:0;border-radius:50%;
  border:1px solid rgba(255,255,255,.16);background:rgba(255,255,255,.05)}
:root[data-theme="day"] .tgl{border-color:rgba(20,40,30,.14);background:rgba(20,40,30,.04)}
.tgl i{position:absolute;inset:0;width:auto;height:auto;border-radius:50%;
  display:grid;place-items:center;
  transform:none!important;background:none!important;box-shadow:none!important}
.tgl svg{position:absolute;width:18px;height:18px}
:root[data-theme="night"] .tgl .s-moon{fill:#CFE6FF}
:root[data-theme="day"]   .tgl .s-sun{fill:#E0A24A}
:root[data-theme="day"]   .tgl .s-sun path{stroke:#E0A24A}

/* ═══ DAY — the bright-sky version of the same hero ═══════════════
   Blue sky graded to near-white at the horizon, a sun burning in the top
   right, and soft cloud banks. Same layout, same globe, same leaves. */
:root[data-theme="day"]{
  --bg-0:#CFEAFB; --bg-1:#E8F6FE; --bg-2:#BFE2F8;
  --sky:
    /* the sun, top right */
    radial-gradient(22% 22% at 84% 14%,rgba(255,252,226,.98) 0%,rgba(255,246,190,.70) 26%,transparent 62%),
    radial-gradient(52% 46% at 86% 12%,rgba(255,240,170,.44) 0%,transparent 68%),
    /* cloud banks */
    radial-gradient(38% 20% at 14% 78%,rgba(255,255,255,.92) 0%,transparent 66%),
    radial-gradient(30% 16% at 74% 84%,rgba(255,255,255,.86) 0%,transparent 68%),
    radial-gradient(26% 14% at 40% 26%,rgba(255,255,255,.70) 0%,transparent 70%),
    radial-gradient(34% 18% at 96% 58%,rgba(255,255,255,.80) 0%,transparent 68%),
    /* the sky itself */
    linear-gradient(178deg,#9FD8F7 0%,#C6E9FB 42%,#E6F6FE 78%,#F2FBFF 100%);
  --sky-op:.10;
}
:root[data-theme="day"] .heroX .hx-h{color:#123553}
:root[data-theme="day"] .heroX .hx-h .hl{color:#3FBF63}
:root[data-theme="day"] .heroX .lead{color:#3F5C74}
:root[data-theme="day"] .heroX .pill{color:#1E7CB8;
  background:rgba(255,255,255,.72);border-color:rgba(255,255,255,.9);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
:root[data-theme="day"] .heroX .b-line{color:#1B4E70;
  background:rgba(255,255,255,.72);border-color:rgba(255,255,255,.9);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
:root[data-theme="day"] .heroX .b-line:hover{background:rgba(255,255,255,.92)}
:root[data-theme="day"] .hx-art .ring{border-color:rgba(255,255,255,.7)}
:root[data-theme="day"] .heroX .atmo{
  box-shadow:0 0 60px 14px rgba(255,255,255,.60),0 0 150px 44px rgba(150,215,250,.44)!important}
:root[data-theme="day"] .lv .l{fill:#54C46E}
/* the drifting specks read as pollen in daylight, not stars */
:root[data-theme="day"]{--mote:#FFFFFF;--mote-lo:.20;--mote-hi:.85}

/* ═══ a slow cross-fade when the theme is switched ══════════════════ */
body,.sky,.head,.card,.btn,.nav a,.hx-h,.heroX .lead{
  transition:background-color .55s var(--e-soft),color .55s var(--e-soft),
             border-color .55s var(--e-soft)}
.sky{transition:background 0s}          /* the sheet itself cross-fades below */
.sky::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:var(--sky);opacity:0;transition:opacity .55s var(--e-soft)}
.tgl svg{transition:opacity .45s var(--e-soft),transform .6s var(--e-out)}

/* ── hero layout ────────────────────────────────────────────────── */
.heroX{position:relative;min-height:100svh;display:grid;
  /* an explicit 1fr column: without it the implicit column is content-sized,
     the .hx percentage width has nothing to resolve against and collapses */
  grid-template-columns:minmax(0,1fr);align-content:center;justify-items:center;
  padding:clamp(96px,12vh,140px) clamp(16px,3vw,32px) clamp(48px,7vh,80px);overflow:hidden}
.heroX .halo{display:none}
/* the mock-up hero is clean sky — the wooded horizon stays on the pages below */
.heroX .treeline{display:none}
/* app.js adds a .woods horizon to any page that has no .treeline, so taking
   the treeline out of the hero made one appear. The home page wants neither. */
body:has(.heroX) .woods{display:none}
.hx{position:relative;z-index:3;display:grid;align-items:center;
  grid-template-columns:minmax(0,1.02fr) minmax(0,1fr);
  gap:clamp(24px,4vw,72px);width:min(1320px,100%)}
.hx-copy{text-align:left}

.heroX .pill{display:inline-flex;align-items:center;gap:9px;padding:8px 16px;
  border-radius:var(--r-pill);font-size:.78rem;font-weight:700;letter-spacing:.08em;
  color:#6EE787;background:rgba(110,231,135,.09);
  border:1px solid rgba(110,231,135,.26)}
:root[data-theme="day"] .heroX .pill{color:#1E8B4A;background:rgba(30,139,74,.08);
  border-color:rgba(30,139,74,.22)}
.heroX .pill em{width:13px;height:13px;border-radius:0;background-color:currentColor;
  -webkit-mask:var(--leaf) center/contain no-repeat;mask:var(--leaf) center/contain no-repeat}

.hx-h{margin:clamp(18px,2.4vw,26px) 0 0;display:flex;flex-direction:column;
  font-size:clamp(2.5rem,5.6vw,4.5rem);font-weight:800;line-height:1.06;
  letter-spacing:-.035em;color:#fff}
:root[data-theme="day"] .hx-h{color:var(--ink)}
.hx-h .hl{position:relative;color:#6EE787;width:fit-content}
:root[data-theme="day"] .hx-h .hl{color:#1E8B4A}
/* .tip is also a standalone callout box in style.css (padding 20px 24px, a
   border and a background). That component's box was leaking into this leaf,
   rendering a .26em mark at ~61px — seven times its size — so on a phone it
   sat on top of the headline. Same class name, two different things; the leaf
   has to state its own box. */
.hx-h .tip{display:inline-block;font-size:inherit;margin-left:.14em;vertical-align:.42em;
  width:.26em;height:.26em;
  background-color:currentColor;transform:rotate(18deg);
  -webkit-mask:var(--leaf) center/contain no-repeat;mask:var(--leaf) center/contain no-repeat;
  padding:0;margin-top:0;border:0;background-image:none;border-radius:0;line-height:1}

.heroX .lead{margin-top:clamp(16px,2vw,22px);max-width:34ch;
  font-size:clamp(.98rem,1.2vw,1.06rem);line-height:1.8;color:rgba(206,220,234,.86)}
:root[data-theme="day"] .heroX .lead{color:var(--ink-2)}
.heroX .cta{justify-content:flex-start;margin-top:clamp(22px,3vw,32px)}
.heroX .b-fill{color:#06301A;border:0}
.heroX .b-fill::before{background:linear-gradient(100deg,#6EE787 0%,#8FF0A4 52%,#3FCF6A 100%)}
.heroX .b-line{color:#EAF3F0;border:1px solid rgba(255,255,255,.20);
  background:rgba(255,255,255,.05)}
.heroX .b-line::before{display:none}
.heroX .b-line:hover{background:rgba(255,255,255,.12);color:#fff}
:root[data-theme="day"] .heroX .b-line{color:var(--ink);border-color:var(--panel-line);
  background:var(--panel)}

/* ── globe inside a thin orbital ring ───────────────────────────── */
.hx-art{position:relative;display:grid;place-items:center}
.hx-art .ring{position:absolute;width:min(126%,660px);aspect-ratio:1;border-radius:50%;
  border:1px solid rgba(150,200,235,.16);pointer-events:none}
:root[data-theme="day"] .hx-art .ring{border-color:rgba(40,90,70,.14)}
.heroX .orbit{width:min(520px,90%);margin:0}
.heroX .globe .land{background-image:url("../earth-v9b.jpg")!important;
  animation-duration:150s!important}
.heroX .globe .cloud{opacity:.05;animation-duration:210s!important}
.heroX .globe .shade{background:
  radial-gradient(circle at 26% 30%,rgba(255,255,255,.30) 0%,rgba(255,255,255,.08) 24%,transparent 48%),
  radial-gradient(circle at 80% 78%,rgba(0,8,26,.46) 0%,rgba(0,8,26,.16) 46%,transparent 74%),
  radial-gradient(circle at 50% 50%,transparent 54%,rgba(0,8,24,.12) 76%,rgba(0,8,24,.38) 94%,rgba(0,8,24,.52) 100%)!important}
.heroX .atmo{box-shadow:0 0 60px 10px rgba(120,205,255,.34),0 0 170px 52px rgba(56,140,225,.20)!important}
/* a hard bright rim on the sunward limb, the way the mock-up lights it */
.heroX .globe::after{box-shadow:
  inset 0 0 26px 2px rgba(150,215,255,.34),
  inset 14px 14px 34px -10px rgba(210,240,255,.45),
  inset -18px -18px 40px -12px rgba(0,10,30,.55)!important}

/* ── drifting leaves ────────────────────────────────────────────── */
.lv{position:absolute;inset:0;z-index:2;pointer-events:none}
.lv .l{position:absolute;fill:#4FBF6B;opacity:.9;animation:lvFloat 18s ease-in-out infinite}
.lv .l1{left:-3%;top:16%;width:190px;filter:blur(7px);opacity:.55;animation-duration:26s}
.lv .l2{left:4%;bottom:-4%;width:230px;filter:blur(9px);opacity:.50;animation-duration:31s;animation-delay:-6s}
.lv .l3{right:-2%;bottom:2%;width:250px;filter:blur(10px);opacity:.45;animation-duration:29s;animation-delay:-12s}
.lv .l4{right:8%;top:12%;width:44px;opacity:.85;animation-delay:-3s}
.lv .l5{left:47%;top:38%;width:26px;opacity:.70;animation-duration:22s;animation-delay:-8s}
.lv .l6{left:44%;bottom:14%;width:30px;opacity:.75;animation-duration:24s;animation-delay:-15s}
.lv .l7{right:26%;bottom:26%;width:22px;opacity:.60;animation-duration:20s;animation-delay:-2s}
@keyframes lvFloat{
  0%,100%{transform:translate3d(0,0,0) rotate(0deg)}
  50%    {transform:translate3d(10px,-16px,0) rotate(9deg)}
}
html.scrolling .lv .l{animation-play-state:paused}
@media (prefers-reduced-motion:reduce){ .lv .l{animation:none} }

/* ── narrow screens: stack, globe first ─────────────────────────── */
@media (max-width:900px){
  .hx{grid-template-columns:1fr;gap:clamp(18px,4vw,30px);text-align:center}
  .hx-copy{text-align:center}
  .hx-art{order:-1}
  .heroX .orbit{width:min(300px,66%)}
  .hx-h{align-items:center}
  .heroX .lead{margin-inline:auto}
  .heroX .cta{justify-content:center}
  .lv .l1,.lv .l2,.lv .l3{opacity:.30}
  .head{top:10px;width:calc(100% - 18px);padding:9px 12px}
}


/* ── the scroll progress bar is gone ────────────────────────────────── */
.progress{display:none!important}

/* ── the company name carries the header ────────────────────────────
   행복한지구 is the business name and was set smaller than the menu items
   beside it. It now leads, with the latin line stepped back underneath. */
.brand{gap:13px}
.head .brand b{font-size:clamp(1.24rem,1.5vw,1.46rem);font-weight:800;
  letter-spacing:-.035em;line-height:1.1}
.head .brand i{font-size:.58rem;letter-spacing:.24em;opacity:.62;margin-top:2px}
.brand .bmark{width:clamp(42px,4.4vw,52px)}

/* ── day: nav links need to hold up on white glass ──────────────────
   Measured 3.19:1 against the bar, which is below the 4.5:1 floor. */
:root[data-theme="day"] .nav a{color:#243A31}
:root[data-theme="day"] .nav a:hover{color:#0F1A14}
:root[data-theme="day"] .head .brand b{color:#14251C}
:root[data-theme="day"] .head .brand i{color:#4A5A50;opacity:1}

/* ── the wooded horizon stays ───────────────────────────────────────
   app.js draws .woods on any page without a .treeline; the new hero has no
   treeline of its own, so this is what puts the trees back along the bottom. */
body:has(.heroX) .woods{display:block}

/* ── mobile ────────────────────────────────────────────────────────
   The drawer is a full-height sheet again, and the hero stacks with the
   globe above the words. */
@media (max-width:1020px){
  .head{top:10px;width:calc(100% - 16px);padding:11px 12px 11px 14px;border-radius:14px}
  /* the desktop rules made .nav transparent for the glass bar; the drawer is a
     solid sheet and has to clear the floating header, not sit under it */
  .nav{margin:0;background:var(--bg-0)!important;
    padding-top:98px;box-shadow:-18px 0 46px -18px rgba(0,0,0,.55)}
  :root[data-theme="day"] .nav{background:#EAF6FE!important;
    box-shadow:-18px 0 46px -20px rgba(30,80,120,.35)}
  .nav a::after{display:none}
  .nav a[aria-current="page"]{color:#6EE787}
  :root[data-theme="day"] .nav a[aria-current="page"]{color:#1E8B4A}
  .burger{display:flex;margin-left:auto}
  .heroX{padding-top:104px;min-height:auto}
  .hx{width:min(560px,92%)}
  .hx-h{font-size:clamp(2.1rem,9vw,3rem)}
  .heroX .lead{font-size:1rem}
  .heroX .orbit{width:min(280px,74%)}
  .hx-art .ring{width:min(122%,340px)}
  .lv .l1{width:120px}.lv .l2{width:150px}.lv .l3{width:160px}
  .lv .l4{width:30px}.lv .l5,.lv .l6,.lv .l7{width:20px}
}
@media (max-width:560px){
  .head .brand b{font-size:1.1rem}
  .head .brand i{font-size:.52rem;letter-spacing:.18em}
  .brand .bmark{width:38px}
  .heroX .cta{flex-direction:column;align-items:stretch;width:100%}
  .heroX .cta .btn{width:100%}
}

/* ═══ DAY MODE ON THE APP PAGE ═════════════════════════════════════
   app.html carries body.dark-page, which style.css uses to force light nav
   text and a dark bar, and .stage is a dark canvas in BOTH themes. Against
   the new white glass bar that left the menu unreadable, and day mode never
   actually arrived on the page. In daylight it now behaves like every other
   page; at night nothing changes. */
:root[data-theme="day"] body.dark-page .brand b{color:#14251C}
:root[data-theme="day"] body.dark-page .brand i{color:#4A5A50}
:root[data-theme="day"] body.dark-page .nav a{color:#243A31}
:root[data-theme="day"] body.dark-page .nav a:hover{color:#0F1A14}
:root[data-theme="day"] body.dark-page .nav a[aria-current="page"]{color:#1E8B4A}
:root[data-theme="day"] body.dark-page .head::after{
  background:linear-gradient(180deg,rgba(255,255,255,.68),rgba(255,255,255,.48));
  border-color:rgba(255,255,255,.72)}
:root[data-theme="day"] body.dark-page .tgl{
  background:rgba(20,40,30,.05);border-color:rgba(20,40,30,.16)}
:root[data-theme="day"] body.dark-page .burger{
  background:rgba(20,40,30,.05);border-color:rgba(20,40,30,.16)}
:root[data-theme="day"] body.dark-page .burger i{background:#14251C}

/* the dark canvas itself lifts into daylight */
:root[data-theme="day"] .stage{background:transparent!important;color:var(--ink)!important}
:root[data-theme="day"] .stage::before,
:root[data-theme="day"] .stage::after{display:none!important}
:root[data-theme="day"] .stage .d1,
:root[data-theme="day"] .stage .d2,
:root[data-theme="day"] .stage h1,
:root[data-theme="day"] .stage h2,
:root[data-theme="day"] .stage h3{color:var(--ink)!important}
:root[data-theme="day"] .stage .lead,
:root[data-theme="day"] .stage .app-note{color:var(--ink-2)!important}
:root[data-theme="day"] .stage .kicker{color:#1E8B4A!important;
  background:rgba(30,139,74,.08)!important;border-color:rgba(30,139,74,.22)!important}
:root[data-theme="day"] .stage .quiz-wait,
:root[data-theme="day"] .stage .quiz-open,
:root[data-theme="day"] .stage .quiz-how,
:root[data-theme="day"] .stage .qr-card,
:root[data-theme="day"] .stage .qr-panel{
  background:rgba(255,255,255,.86)!important;border-color:var(--panel-line)!important;
  color:var(--ink)!important}
:root[data-theme="day"] .stage .quiz-open b,
:root[data-theme="day"] .stage .quiz-wait b,
:root[data-theme="day"] .stage .quiz-how h3,
:root[data-theme="day"] .stage .qr-cap b{color:var(--ink)!important}
:root[data-theme="day"] .stage .quiz-open p,
:root[data-theme="day"] .stage .quiz-wait p,
:root[data-theme="day"] .stage .qr-cap span,
:root[data-theme="day"] .stage .quiz-tip,
:root[data-theme="day"] .stage .quiz-steps li{color:var(--ink-2)!important}
:root[data-theme="day"] .stage .quiz-steps li b{color:var(--ink)!important}
:root[data-theme="day"] .stage .b-fill{color:#fff!important}
:root[data-theme="day"] .stage .b-fill::before{
  background:linear-gradient(100deg,#3FBF63,#2FA854)!important}
:root[data-theme="day"] .stage .b-line{color:#1B4E70!important;
  background:rgba(255,255,255,.8)!important;border-color:var(--panel-line)!important}

/* ═══ DAYLIGHT ON THE GLOBE ════════════════════════════════════════
   In daylight the sun is up, so the globe is lit harder: a brighter map, a
   stronger specular on the sunward shoulder and a warm rim where the light
   grazes the limb. */
:root[data-theme="day"] .heroX .globe .land{filter:brightness(1.16) saturate(1.10) contrast(1.04)}
:root[data-theme="day"] .heroX .globe .shade{background:
  radial-gradient(circle at 24% 26%,rgba(255,255,255,.52) 0%,rgba(255,255,255,.16) 26%,transparent 52%),
  radial-gradient(circle at 82% 80%,rgba(10,40,70,.30) 0%,rgba(10,40,70,.10) 46%,transparent 74%),
  radial-gradient(circle at 50% 50%,transparent 58%,rgba(10,40,70,.08) 80%,rgba(10,40,70,.22) 100%)!important}
:root[data-theme="day"] .heroX .globe::after{box-shadow:
  inset 0 0 30px 3px rgba(255,250,225,.42),
  inset 16px 16px 38px -10px rgba(255,255,255,.62),
  inset -16px -16px 36px -14px rgba(20,60,100,.34)!important}


/* ── day: nav links needed a touch more weight on the glass ────────── */
:root[data-theme="day"] .nav a,
:root[data-theme="day"] body.dark-page .nav a{color:#1C2E26}
:root[data-theme="day"] .nav a:hover,
:root[data-theme="day"] body.dark-page .nav a:hover{color:#0B120E}

/* ═══ MOBILE MENU — redesigned ══════════════════════════════════════
   The drawer was a stack of ten identical outlined boxes. It now reads as a
   sheet: a header with the company name, links as plain rows with a hairline
   between them, a green marker on the current page, and the outbound links
   grouped at the bottom. */
@media (max-width:1020px){
  .nav{width:min(340px,88vw);padding:0 0 calc(24px + env(safe-area-inset-bottom));
    gap:0;border-left:0;border-radius:20px 0 0 20px;overflow:hidden auto;
    box-shadow:-24px 0 60px -20px rgba(0,0,0,.6)}
  /* a title strip so the panel has a top edge of its own */
  .nav::before{content:"행복한지구";display:block;
    padding:26px 24px 16px;margin-bottom:6px;
    font-size:1.16rem;font-weight:800;letter-spacing:-.03em;color:var(--ink);
    border-bottom:1px solid var(--panel-line)}
  .nav a{padding:16px 24px;margin:0;border:0;border-radius:0;font-size:1.06rem;
    font-weight:600;color:var(--ink-2);
    border-bottom:1px solid color-mix(in srgb,var(--panel-line) 60%,transparent);
    display:flex;align-items:center;gap:10px}
  .nav a::before{display:none}
  .nav a:hover,.nav a:active{background:color-mix(in srgb,var(--brand) 10%,transparent)}
  /* the current page gets a green bar and green type, nothing else */
  .nav a[aria-current="page"]{color:var(--brand);
    box-shadow:inset 4px 0 0 var(--brand);
    background:color-mix(in srgb,var(--brand) 9%,transparent)}
  .nav a.out{color:var(--brand);font-weight:700}
  .nav a.out::after{content:"↗";margin-left:auto;font-size:.9em;opacity:.75}
  /* the burger becomes a close button while the sheet is open */
  .burger{width:44px;height:44px;border-radius:12px}
  .scrim{backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);
    background:rgba(4,10,18,.55)}
}
@media (max-width:1020px) and (max-height:720px){
  .nav::before{padding:18px 24px 12px}
  .nav a{padding:13px 24px}
}

/* ═══ THE GLOBE — spinning, with a day face and a night face ══════
   A photograph of a sphere has no far side, so it can only sit still. To keep
   the rotation the globe goes back to scrolling a flat map behind a circular
   mask — but the map is now graded from the supplied artwork twice: bright and
   saturated for the lit side, and deep blue with warm light over the land for
   the night side. The earlier sphere cut-outs also carried a sliver of the
   source's grey backdrop inside the mask, which is what put a dark ring around
   the planet; there is no cut-out now, so no ring. */
.heroX .globe{overflow:hidden;border-radius:50%;
  background:radial-gradient(circle at 34% 28%,#7ADAFF 0%,#3BA0F7 46%,#1E7EE8 78%,#1568D6 100%)!important;
  transition:background .9s var(--e-soft)}
:root[data-theme="night"] .heroX .globe{
  background:radial-gradient(circle at 34% 28%,#1E5C96 0%,#14417A 46%,#0D2E5C 78%,#0A2447 100%)!important}

/* The map scrolls behind a circular mask, which is what makes the globe turn.
   It has to be written as longhands: the `background` shorthand also sets
   background-position, and an !important declaration outranks a CSS
   animation — with it there the spin ran and the map never moved. Position is
   therefore the one part left un-important, so spinmap can drive it. */
.heroX .globe .land{
  /* Two layers: the texture, and under it a 64x32 blurred copy inlined as a
     data URI. The real map is 168KB and takes about two seconds on a phone —
     measured — during which the globe was an empty circle. The placeholder
     costs under 1KB, arrives inside the stylesheet, and is completely covered
     the moment the real texture decodes, so the finished picture is unchanged. */
  background-image:url("../earth-night-map.jpg?v=6"),url("data:image/jpeg;base64,/9j/2wBDABMTExMUExUYGBUeIB0gHiwoJSUoLEMwMzAzMENlP0o/P0o/ZVlsWFJYbFmhfnBwfqG6nJScuuHJyeH/////////2wBDARMTExMUExUYGBUeIB0gHiwoJSUoLEMwMzAzMENlP0o/P0o/ZVlsWFJYbFmhfnBwfqG6nJScuuHJyeH/////////wgARCAAgAEADASIAAhEBAxEB/8QAGQAAAwEBAQAAAAAAAAAAAAAAAQIDBAUA/8QAGAEAAwEBAAAAAAAAAAAAAAAAAQIEAwD/2gAMAwEAAhADEAAAAOO+S9c+0cyjcV1mV8bpKjMClqBHzLidGeZBed4uP//EACIQAAICAgICAgMAAAAAAAAAAAECABEDEgQhMVEiQRMygf/aAAgBAQABPwDHkKilqvRg1fbZgD6EwnAMiBsalSanPycYvrgQdeTCXrtpSgg3G0Y+Kg/FoBXfuBfiGuFQU2hcjqcfE+V6URuJlB+VV7jY8a0GFEeZkOP6EFE9mBW1v6gYw90K/sx5nxE6NUPJzMBseozO2zQAv4EKkGoMjldB4jcHMqhqj7ahQIyhB+wNzdiAPoTq6DTXJiAIIIjOSxJn/8QAHxEAAgICAwADAAAAAAAAAAAAAQIDEQAhBBIxE0FC/9oACAECAQE/AJ3liog3ZrzFBUfK5IoeY3Ll/NVnHeZ1tm1hI8NYisQ4k2pOgchgWLvobOL3DnQ6fWf/xAAfEQACAgEEAwAAAAAAAAAAAAABAgARIQMQEjEiUYH/2gAIAQMBAT8AQBvgl34gDMGj7jhQTtgUV7jOWrJhC8ezc//Z")!important;
  background-repeat:repeat-x,repeat-x!important;
  background-size:200% 100%,200% 100%!important;
  background-position:center;
  animation:spinmap 72s linear infinite!important;
  border-radius:0;transition:opacity .9s var(--e-soft)}
:root[data-theme="day"] .heroX .globe .land{
  background-image:url("../earth-day-map.jpg?v=6"),url("data:image/jpeg;base64,/9j/2wBDABMTExMUExUYGBUeIB0gHiwoJSUoLEMwMzAzMENlP0o/P0o/ZVlsWFJYbFmhfnBwfqG6nJScuuHJyeH/////////2wBDARMTExMUExUYGBUeIB0gHiwoJSUoLEMwMzAzMENlP0o/P0o/ZVlsWFJYbFmhfnBwfqG6nJScuuHJyeH/////////wgARCAAgAEADASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAgMEAQX/xAAXAQADAQAAAAAAAAAAAAAAAAABAgME/9oADAMBAAIQAxAAAAASho0ZLB5hujV2FktE5E954FDtSoFoRNcaTBNNkrD/xAAlEAACAgEDBAEFAAAAAAAAAAABAgADEQQSIRMiMVFBBSMycZH/2gAIAQEAAT8Arv2LhAAD8GBhZuy4B9CVNSLEBRSucTX20M22hRkeTGawDl8GYUOCTH6TtnGIp0uwAr3e4E+2LA3zNqGstmPaV4mlre6zCL+4+kuDdwGPcNVSgBhgjzLjVztGJWUdgGYiLVYa9xyFiuQcA8Ru7A28e5Ve9DNsaHV3sMsciFrXDt/YAbhgAxq2Vtoiai506SgFY30vUIm+OtmxUA5+Y9aUp+asSOZ1XYKueBMKWCrZ5nT1GnQFSCsa5i5dvM//xAAeEQABBAIDAQAAAAAAAAAAAAACAAEDERIhBBMxQf/aAAgBAgEBPwCc5IqId2VeIbYOw7akXLm3jVLjnNIFkWmVt4VIBJ8xk2LvplDAMWem26DsY3pmw+L/xAAeEQACAwABBQAAAAAAAAAAAAABAgARIRIDBEFSof/aAAgBAwEBPwDpgNh8C4Wu0UDYvb+32OFViAATOJItblAUVwgRnZ+OnIyqFGnlP//Z")!important}
.heroX .globe .cloud{opacity:.07;animation-duration:104s!important;mix-blend-mode:normal}

/* sphere shading: a lit shoulder, a terminator, and limb darkening all round */
.heroX .globe .shade{background:
  radial-gradient(circle at 28% 26%,rgba(255,255,255,.30) 0%,rgba(255,255,255,.09) 24%,transparent 50%),
  radial-gradient(circle at 80% 80%,rgba(0,10,30,.42) 0%,rgba(0,10,30,.14) 46%,transparent 74%),
  radial-gradient(circle at 50% 50%,transparent 56%,rgba(0,8,26,.10) 78%,rgba(0,8,26,.34) 94%,rgba(0,8,26,.48) 100%)
  !important}
:root[data-theme="day"] .heroX .globe .shade{background:
  radial-gradient(circle at 24% 24%,rgba(255,255,255,.48) 0%,rgba(255,255,255,.14) 26%,transparent 52%),
  radial-gradient(circle at 82% 82%,rgba(10,40,70,.26) 0%,rgba(10,40,70,.08) 46%,transparent 74%),
  radial-gradient(circle at 50% 50%,transparent 60%,rgba(10,40,70,.07) 82%,rgba(10,40,70,.20) 100%)
  !important}

/* the atmosphere rim */
.heroX .globe::after{box-shadow:
  inset 0 0 24px 2px rgba(150,215,255,.30),
  inset 12px 12px 32px -10px rgba(200,235,255,.34),
  inset -16px -16px 36px -12px rgba(0,10,30,.50)!important}
:root[data-theme="day"] .heroX .globe::after{box-shadow:
  inset 0 0 30px 3px rgba(255,250,225,.40),
  inset 16px 16px 38px -10px rgba(255,255,255,.60),
  inset -16px -16px 36px -14px rgba(20,60,100,.30)!important}

.heroX .atmo{border-radius:50%;
  box-shadow:0 0 70px 16px rgba(120,205,255,.26),0 0 180px 60px rgba(56,140,225,.16)!important;
  transition:box-shadow .9s var(--e-soft)}
:root[data-theme="day"] .heroX .atmo{
  box-shadow:0 0 74px 18px rgba(255,252,225,.55),0 0 190px 66px rgba(150,215,250,.42)!important}

/* ═══ THE SUN — a real disc, defined once ══════════════════════════
   A white core, a warm corona and a ring of rays. Position, scale and colour
   are set by the single transition block further down; nothing else touches
   them, so the two states cannot fight. */
.daystar{right:11%!important;width:min(26vw,300px)!important;
  background:
    radial-gradient(circle,rgba(255,255,255,1) 0%,rgba(255,251,214,.98) 16%,
      rgba(255,236,160,.72) 34%,rgba(255,214,120,.32) 54%,transparent 74%)!important;
  opacity:1!important;animation:none!important}
.daystar::after{content:"";position:absolute;inset:-46%;border-radius:50%;
  background:repeating-conic-gradient(from 0deg,
    rgba(255,244,186,.34) 0deg 3deg,transparent 3deg 15deg);
  -webkit-mask:radial-gradient(circle,transparent 30%,#000 42%,transparent 78%);
  mask:radial-gradient(circle,transparent 30%,#000 42%,transparent 78%);
  animation:sunSpin 140s linear infinite}
@keyframes sunSpin{to{transform:rotate(360deg)}}
html.scrolling .daystar::after{animation-play-state:paused}

/* ═══ DAY SKY — matched to day.png ═════════════════════════════════ */
:root[data-theme="day"]{
  --bg-0:#BFE4FA; --bg-1:#E4F4FE; --bg-2:#A9D8F6;
  --sky:
    /* the sun's own wash, top right */
    radial-gradient(38% 34% at 84% 12%,rgba(255,250,214,.72) 0%,transparent 66%),
    /* cloud banks, low and soft */
    radial-gradient(42% 20% at 10% 82%,rgba(255,255,255,.96) 0%,transparent 68%),
    radial-gradient(34% 17% at 70% 88%,rgba(255,255,255,.92) 0%,transparent 70%),
    radial-gradient(30% 15% at 44% 96%,rgba(255,255,255,.86) 0%,transparent 72%),
    radial-gradient(24% 12% at 26% 24%,rgba(255,255,255,.74) 0%,transparent 72%),
    radial-gradient(30% 15% at 95% 62%,rgba(255,255,255,.82) 0%,transparent 70%),
    /* the sky */
    linear-gradient(178deg,#7FC7EE 0%,#A9DCF7 26%,#CFECFC 60%,#E9F7FE 84%,#F4FBFF 100%);
  --sky-op:.08;
}
/* daylight quiets the night furniture */
:root[data-theme="day"] .motes,
:root[data-theme="day"] .star,
:root[data-theme="day"] .streak{opacity:0!important;transition:opacity 1.2s ease}
:root[data-theme="night"] .motes,
:root[data-theme="night"] .star{transition:opacity 1.2s ease}

/* ═══ the whole switch moves together ══════════════════════════════ */
body,.sky,.head::after,.hx-h,.heroX .lead,.heroX .pill,.card,.btn,.nav a,
.treeline .far,.treeline .near,.woods i{
  transition:background 1.4s cubic-bezier(.22,.61,.36,1),
             background-color 1.4s cubic-bezier(.22,.61,.36,1),
             color .9s ease,border-color .9s ease,opacity 1.2s ease,fill .9s ease!important}
@media (prefers-reduced-motion:reduce){
  .daystar,.daystar::after,body,.sky,.head::after{transition:none!important}
}

/* ── day: the four .feat cards on the app page ──────────────────────
   These sat outside the .stage overrides, so they kept their dark navy fill
   and light body text against the bright sky. */
:root[data-theme="day"] .feat{
  background:rgba(255,255,255,.82)!important;
  border-color:rgba(30,90,140,.16)!important;
  box-shadow:0 6px 22px -14px rgba(20,60,100,.34)}
:root[data-theme="day"] .feat:hover{
  background:rgba(255,255,255,.94)!important;border-color:rgba(63,191,99,.45)!important}
:root[data-theme="day"] .feat h3{color:#123553!important}
:root[data-theme="day"] .feat p{color:#3F5C74!important}
:root[data-theme="day"] .feat .fic{background:rgba(63,191,99,.14)!important}
/* the same treatment for any other card sitting on the daylit page */
:root[data-theme="day"] .stage .card,
:root[data-theme="day"] .feats + * .card{background:rgba(255,255,255,.82)!important;
  border-color:rgba(30,90,140,.16)!important}

/* ═══ SUN & THEME TRANSITION — reworked ════════════════════════════
   The switch now plays as a short scene rather than a cross-fade:

     · the sun climbs an arc, not a straight line — it drifts sideways as it
       rises, the way one actually does
     · it starts large and amber near the horizon and tightens to a small
       white disc overhead, so the colour temperature changes with altitude
     · its rays fade up only once it has cleared the horizon
     · the sky, the trees and the page follow on a slower curve, so the light
       arrives before the ground catches up */
.daystar{
  will-change:transform,top;
  transition:
    top 2.1s cubic-bezier(.24,.66,.28,1),
    transform 2.1s cubic-bezier(.24,.66,.28,1),
    filter 2.1s ease,
    opacity .9s ease!important}
/* No !important on `top` here. An author !important declaration outranks a
   CSS animation, so with it in place the keyframed arc below ran but could
   not move the disc — measured: the sun sat pinned at its night position and
   only its scale animated. The selector already outweighs the base rule. */
:root[data-theme="day"] .daystar{
  top:3%;transform:translateX(0) scale(1);
  filter:saturate(1) brightness(1.06)}
:root[data-theme="night"] .daystar{
  top:106%;transform:translateX(-16vw) scale(1.5);
  filter:saturate(1.5) brightness(.8) hue-rotate(-12deg)}

/* rays only once it is up */
.daystar::after{transition:opacity 1.5s ease .45s,transform 2.1s ease}
:root[data-theme="night"] .daystar::after{opacity:0;transform:scale(.7)}
:root[data-theme="day"]   .daystar::after{opacity:1;transform:scale(1)}

/* the sky changes on a slower, later curve than the sun */
.sky{transition:background 2.4s cubic-bezier(.3,.5,.2,1) .15s!important}
body{transition:background-color 2.4s cubic-bezier(.3,.5,.2,1) .15s!important}
/* the ground lags furthest behind */
.treeline .far,.treeline .near,.treeline .rocks,.woods i{
  transition:fill 2.6s ease .3s,opacity 2.6s ease .3s!important}
/* stars and fireflies fade with the light */
.motes,.star,.streak{transition:opacity 1.8s ease!important}
/* The globe turns its face over the same beat. .land is named separately and
   transitions only its image — a transition on the `background` shorthand
   covers background-position, and a running transition outranks an animation,
   which would stall the spin for its whole 2.1s. */
.heroX .globe,.heroX .globe .shade,.heroX .atmo,
.heroX .globe::after{transition:background 2.1s ease,box-shadow 2.1s ease,
  background-image 2.1s ease!important}
.heroX .globe .land{transition:background-image 2.1s ease,filter 2.1s ease!important}
/* the bar and the type settle last */
.head::after,.hx-h,.heroX .lead,.heroX .pill,.nav a,.card,.btn{
  transition:background 1.9s ease .2s,background-color 1.9s ease .2s,
             color 1.4s ease .25s,border-color 1.4s ease .25s!important}

@media (prefers-reduced-motion:reduce){
  .daystar,.daystar::after,.sky,body,.treeline .far,.treeline .near,
  .motes,.star,.head::after,.hx-h{transition:none!important}
}


/* ── the globe sits on a tilted axis ────────────────────────────────
   Earth leans 23.4 degrees. Tilting the sphere is what makes the sideways
   scroll of the map read as a body turning on its own axis rather than a
   texture sliding past. The moon's orbit is left level so it still crosses
   in front and behind. */
.heroX .globe,.heroX .atmo{transform:rotate(-23.4deg)}
.heroX .globe .shade,.heroX .globe::after{transform:rotate(23.4deg)}

/* ══════════════════════════════════════════════════════════════════
   SMOOTHNESS — no graphics changed, only how they are driven
   ══════════════════════════════════════════════════════════════════
   Everything below is about frame cost and easing. Nothing here alters a
   colour, a size or a layout. */

/* 1. One easing curve for the whole site, so nothing feels out of step. */
:root{--ease-site:cubic-bezier(.32,.72,.28,1)}

/* 2. Promote only the handful of layers that actually move, so the
      compositor can keep them as textures instead of repainting them. */
.heroX .globe .land,.heroX .globe .cloud,.moon,.daystar::after,.lv .l,.aurora i{
  will-change:transform;backface-visibility:hidden;transform-style:flat}

/* 3. Long-running loops run on the compositor at a steady rate. */
.heroX .globe .land,.heroX .globe .cloud,.daystar::after{
  animation-timing-function:linear!important}

/* 4. Everything that moves in the hero stops while the page is scrolling —
      app.js already sets .scrolling, this simply covers the new pieces. */
html.scrolling .lv .l,
html.scrolling .heroX .globe .land,
html.scrolling .heroX .globe .cloud,
html.scrolling .moon,
html.scrolling .daystar::after,
html.scrolling .heroX .orbit{animation-play-state:paused!important}

/* 5. Hover and reveal transitions share one curve and a shorter, calmer
      duration — several were 0.6s with different easings, which is what made
      the page feel loose. */
.card,.btn,.nav a,.pub,.chan,.sns,.tile,.flt,.tab,.shot,.top{
  transition-timing-function:var(--ease-site)!important;
  transition-duration:.28s!important}
.rv{transition:opacity .5s var(--ease-site),transform .5s var(--ease-site)!important}

/* 6. Images fade in rather than popping once decoded. */
.pub-shot img,.grid .shot img,.chan img,.rowthumb{
  transition:opacity .4s var(--ease-site),transform .4s var(--ease-site)}

/* 7. Momentum scrolling on iOS, and no rubber-band chaining from the drawer. */
html,body{-webkit-overflow-scrolling:touch;overscroll-behavior-y:none}

/* 8. Text stays crisp while layers move. */
body{text-rendering:optimizeSpeed}
h1,h2,h3,.d1,.d2,.hx-h{text-rendering:optimizeLegibility}

/* ── day: the gradient headline on the app page ─────────────────────
   .stage paints its highlight with a mint → cyan → violet gradient meant for
   a dark canvas. On the daylit sky those stops are lighter than the
   background, so the words disappeared. In daylight the highlight becomes
   one solid deep green instead. */
:root[data-theme="day"] .stage .gtext,
:root[data-theme="day"] .stage .d1 span,
:root[data-theme="day"] .stage .d2 span,
:root[data-theme="day"] .stage h1 span,
:root[data-theme="day"] .stage h2 span{
  background:none!important;
  -webkit-background-clip:border-box!important;background-clip:border-box!important;
  -webkit-text-fill-color:#1B7F45!important;color:#1B7F45!important}
/* and the plain half of those headings stays full-strength ink */
:root[data-theme="day"] .stage .d1,
:root[data-theme="day"] .stage h1{color:#10202A!important;
  -webkit-text-fill-color:#10202A!important}

/* ── dark mode: a little more colour ────────────────────────────────
   Saturation lifted again across the sky pools and the leaf green, with the
   blues held at the darker level asked for earlier. */
:root[data-theme="night"]{
  --sky:
    radial-gradient(48% 42% at 6% 10%,rgba(24,178,98,.56) 0%,transparent 64%),
    radial-gradient(64% 58% at 72% 38%,rgba(10,86,178,.72) 0%,transparent 68%),
    radial-gradient(46% 40% at 88% 20%,rgba(14,104,182,.44) 0%,transparent 66%),
    radial-gradient(96% 56% at 46% 112%,rgba(3,20,50,.90) 0%,transparent 62%),
    linear-gradient(178deg,#061422 0%,#0A1E33 48%,#08182C 100%);
  --sky-op:.20;
  --brand:#6BEE86; --brand-2:#A9F7B9;
}
:root[data-theme="night"] .aurora i{filter:saturate(1.15)}
:root[data-theme="night"] .heroX .globe .land{filter:saturate(1.14) brightness(1.06)}
:root[data-theme="night"] .heroX .atmo{
  box-shadow:0 0 74px 16px rgba(110,205,255,.34),0 0 190px 64px rgba(46,140,235,.22)!important}


/* ── the nav rail on dark-canvas pages ──────────────────────────────
   style.css paints a rail with `body.dark-page .nav`, which outranks a plain
   `.nav` rule, so the app page kept a dark slate bar sitting inside the light
   glass header. Matched here at the same weight. */
body.dark-page .nav{background:none!important;border:0!important;
  box-shadow:none!important;padding:0!important}
body.dark-page .nav a::before{background:none!important}
:root[data-theme="day"] body.dark-page .nav a[aria-current="page"]{color:#1E8B4A!important}
:root[data-theme="night"] body.dark-page .nav a[aria-current="page"]{color:#6BEE86!important}
body.dark-page .nav a::after{background:#6BEE86}
:root[data-theme="day"] body.dark-page .nav a::after{background:#1E8B4A}

/* ══════════════════════════════════════════════════════════════════
   PERFORMANCE — nothing visual changes
   ══════════════════════════════════════════════════════════════════ */

/* 1. Only paint what is on screen. The hero and the sky are always live; the
      sections below can skip layout and paint until they are approached.
      Sizes are given so the scrollbar does not jump. */
.sec:not(.hero):not(.heroX){content-visibility:auto;contain-intrinsic-size:auto 720px}

/* 2. Isolate the moving layers so a repaint in one cannot dirty another.
      NOT the orbit or the leaves: `contain:paint` clips painting to the
      element's rectangular border box, which sliced the globe's atmosphere
      glow into a visible square and would cut the blurred leaves off at
      their edges. Only the full-viewport sky, which nothing overflows. */
.sky{contain:layout paint}

/* 3. Drop the compositor hints once a layer has stopped moving — a permanent
      will-change keeps a texture in memory for no reason. */
html:not(.scrolling) .aurora i{will-change:auto}

/* 4. The decorative sheets never need hit-testing. */
.sky,.sky *,.lv,.lv *,.treeline,.daystar,.grain{pointer-events:none}

/* 5. Images reserve their space, so nothing reflows as they arrive. */
img{content-visibility:auto}
.pub-shot img,.grid .shot img{contain-intrinsic-size:auto 300px}

/* ── the company name at the head of the H1 ─────────────────────────
   Set small so the three-line headline still carries the composition, but
   it is real, visible text inside the <h1> — which is what a brand search
   reads. */
.hx-h .hx-brand{display:flex;align-items:baseline;gap:10px;
  font-size:clamp(.95rem,1.5vw,1.18rem);font-weight:700;letter-spacing:-.01em;
  margin-bottom:clamp(10px,1.4vw,16px);color:rgba(226,240,235,.92)}
.hx-h .hx-brand em{font-style:normal;font-size:.62em;font-weight:700;
  letter-spacing:.2em;color:#6EE787;opacity:.9}
:root[data-theme="day"] .hx-h .hx-brand{color:#1B3A2C}
:root[data-theme="day"] .hx-h .hx-brand em{color:#1E8B4A}
@media (max-width:900px){ .hx-h .hx-brand{justify-content:center} }

/* ── the live quiz QR, flashed on arrival ──────────────────────────
   "지금 열린 퀴즈 보기" scrolls to the code that is actually up; without a
   beat of movement at the end of the scroll it is not obvious which card
   the button meant, and on a busy screen the grid just looks static. */
@keyframes qrping{
  0%  {transform:translateY(0)      scale(1);   box-shadow:0 0 0 0 rgba(110,231,135,.55)}
  18% {transform:translateY(-6px)   scale(1.03);box-shadow:0 0 0 14px rgba(110,231,135,0)}
  36% {transform:translateY(0)      scale(1);   box-shadow:0 0 0 0 rgba(110,231,135,.4)}
  54% {transform:translateY(-3px)   scale(1.015);box-shadow:0 0 0 12px rgba(110,231,135,0)}
  100%{transform:translateY(0)      scale(1);   box-shadow:0 0 0 0 rgba(110,231,135,0)}
}
.qr-card.ping{animation:qrping 2.2s cubic-bezier(.22,.9,.28,1) both;
  border-color:rgba(110,231,135,.6)!important;z-index:2}
:root[data-theme="day"] .qr-card.ping{border-color:rgba(30,139,74,.55)!important}
@media (prefers-reduced-motion:reduce){ .qr-card.ping{animation:none} }

/* ── a QR that carries a link is itself the link ───────────────────
   The panel keeps its white ground (a QR needs the contrast to scan), so the
   affordance is a caption strip that rises on hover and a lift on the card. */
.qr-panel.hit{display:block;position:relative;overflow:hidden;cursor:pointer;
  transition:transform .32s cubic-bezier(.22,.9,.28,1),box-shadow .32s ease}
.qr-panel.hit:hover{transform:translateY(-2px)}
.qr-panel.hit:focus-visible{outline:3px solid #6EE787;outline-offset:3px}
.qr-tap{position:absolute;left:0;right:0;bottom:0;padding:7px 8px;
  font-size:.78rem;font-weight:700;letter-spacing:-.01em;text-align:center;color:#fff;
  background:linear-gradient(0deg,rgba(9,32,20,.94),rgba(9,32,20,.72));
  transform:translateY(101%);transition:transform .3s cubic-bezier(.22,.9,.28,1)}
.qr-panel.hit:hover .qr-tap,.qr-panel.hit:focus-visible .qr-tap{transform:translateY(0)}
/* Touch has no hover, and that is exactly where tapping the code matters. */
@media (hover:none){ .qr-tap{transform:translateY(0)} }
@media (prefers-reduced-motion:reduce){
  .qr-panel.hit,.qr-tap{transition:none}
}

/* ── day: the small mint accents on the app page ────────────────────
   The stage's accent is #63FFCE, drawn for a near-black canvas. In daylight
   the same accents sit on a white card — the "바로 열기 →" link measured about
   1.4:1 there, i.e. the words were simply not there. Each becomes a deep
   green that keeps the hue and clears 4.5:1. */
:root[data-theme="day"] .stage .qr-go,
:root[data-theme="day"] .stage .applist li::before{color:#127038!important}
:root[data-theme="day"] .stage .qr-go:hover{color:#0C5228!important}
:root[data-theme="day"] .stage .quiz-steps li::marker{color:#146B35!important}
:root[data-theme="day"] .stage .app-badge{color:#0F5D33!important;
  background:rgba(30,139,74,.10)!important;border-color:rgba(30,139,74,.28)!important}
:root[data-theme="day"] .stage .app-badge em{background:#1E8B4A!important;
  box-shadow:0 0 0 0 rgba(30,139,74,.55)!important}

/* ═══ SUNSET / SUNRISE AS A SCENE ══════════════════════════════════
   The set used to be the rise's transition played backwards, and that curve
   is heavily front-loaded: measured on the live site the disc fell from y=176
   to y=868 in 800ms and spent the remaining 1.3s travelling below the fold.
   A drop that fast reads as the sun vanishing, not setting.

   So each direction gets its own hand-placed arc, run as a keyframe animation
   rather than a transition. app.js adds .to-night / .to-day for the length of
   the scene — a class, not the theme attribute, so opening a page already in
   night mode does not play a sunset at nobody.

   The path: the disc drifts sideways as it falls, swells and reddens the way
   a low sun does through more atmosphere, slows as it meets the horizon —
   that is the beat worth watching — then slips under. The 100% frames are the
   resting states exactly, so nothing jumps when the class comes off. */
@keyframes sunSet{
  0%   {top:3%;   transform:translateX(0)     scale(1);    filter:saturate(1) brightness(1.06)}
  18%  {top:20%;  transform:translateX(-2.4vw) scale(1.09); filter:saturate(1.14) brightness(1.05) hue-rotate(-3deg)}
  38%  {top:42%;  transform:translateX(-5.6vw) scale(1.19); filter:saturate(1.3) brightness(1.02) hue-rotate(-7deg)}
  58%  {top:62%;  transform:translateX(-8.8vw) scale(1.3);  filter:saturate(1.48) brightness(.98) hue-rotate(-11deg)}
  74%  {top:76%;  transform:translateX(-11.4vw) scale(1.4); filter:saturate(1.64) brightness(.93) hue-rotate(-15deg)}
  86%  {top:86%;  transform:translateX(-13.4vw) scale(1.47);filter:saturate(1.76) brightness(.88) hue-rotate(-18deg)}
  100% {top:106%; transform:translateX(-16vw)  scale(1.5);  filter:saturate(1.5) brightness(.8) hue-rotate(-12deg)}
}
@keyframes sunRise{
  0%   {top:106%; transform:translateX(-16vw)  scale(1.5);  filter:saturate(1.5) brightness(.8) hue-rotate(-12deg)}
  16%  {top:88%;  transform:translateX(-13.6vw) scale(1.46);filter:saturate(1.74) brightness(.9) hue-rotate(-17deg)}
  32%  {top:74%;  transform:translateX(-11vw)  scale(1.39); filter:saturate(1.6) brightness(.96) hue-rotate(-13deg)}
  54%  {top:52%;  transform:translateX(-7.2vw) scale(1.25); filter:saturate(1.34) brightness(1.01) hue-rotate(-8deg)}
  76%  {top:26%;  transform:translateX(-3.4vw) scale(1.12); filter:saturate(1.14) brightness(1.04) hue-rotate(-3deg)}
  100% {top:3%;   transform:translateX(0)      scale(1);    filter:saturate(1) brightness(1.06)}
}
/* A running transition outranks an animation on the same property, and
   .daystar carries transitions on exactly top/transform/filter. They are
   switched off for the length of the scene so the arc is the only thing
   moving the disc; the resting states either side are identical to the
   keyframes' end frames, so nothing jumps when the class comes off. */
:root.to-night .daystar,:root.to-day .daystar,
:root.to-night .daystar::after,:root.to-day .daystar::after,
:root.to-night .sky::after,:root.to-day .sky::after{transition:none!important}
:root.to-night .daystar{animation:sunSet 2.7s linear both!important}
:root.to-day   .daystar{animation:sunRise 2.5s linear both!important}

/* the rays retract into the disc as it goes down, and open out as it climbs */
@keyframes raysOut{0%{opacity:1;transform:scale(1)}62%{opacity:.55;transform:scale(.88)}100%{opacity:0;transform:scale(.7)}}
@keyframes raysIn {0%{opacity:0;transform:scale(.7)}46%{opacity:.35;transform:scale(.86)}100%{opacity:1;transform:scale(1)}}
:root.to-night .daystar::after{animation:raysOut 2.7s ease-in both,sunSpin 140s linear infinite!important}
:root.to-day   .daystar::after{animation:raysIn 2.5s ease-out both,sunSpin 140s linear infinite!important}

/* ── the warm band the low sun throws across the whole sky ──────────
   .sky::after was an inert cross-fade sheet left at opacity 0. Reused here so
   every page gets the wash without a single new element in the markup. It
   paints above the disc, which is what tints it. */
:root.to-night .sky::after{
  background:linear-gradient(180deg,rgba(255,168,72,0) 0%,rgba(255,150,58,.20) 38%,
    rgba(255,104,44,.36) 68%,rgba(126,44,88,.34) 100%)!important;
  animation:dusk 2.7s ease-out both}
:root.to-day .sky::after{
  background:linear-gradient(180deg,rgba(255,214,132,0) 0%,rgba(255,198,110,.20) 42%,
    rgba(255,160,88,.30) 72%,rgba(255,206,146,.22) 100%)!important;
  animation:dawn 2.5s ease-out both}
@keyframes dusk{0%{opacity:0}34%{opacity:1}72%{opacity:.82}100%{opacity:0}}
@keyframes dawn{0%{opacity:0}30%{opacity:.92}68%{opacity:.7}100%{opacity:0}}

/* the sky itself holds its light a beat longer on the way down, so the light
   goes after the sun rather than with it */
:root[data-theme="night"] .sky{transition:background 2.9s cubic-bezier(.4,.08,.3,1) .38s!important}
:root[data-theme="night"] body{transition:background-color 2.9s cubic-bezier(.4,.08,.3,1) .38s!important}

@media (prefers-reduced-motion:reduce){
  :root.to-night .daystar,:root.to-day .daystar,
  :root.to-night .daystar::after,:root.to-day .daystar::after,
  :root.to-night .sky::after,:root.to-day .sky::after{animation:none!important}
}

/* ═══ ICONS — one drawn set, no OS emoji ═══════════════════════════
   Every glyph on the site is now an inline SVG stroked in currentColor.
   Sizing is in em so each icon inherits the scale its container already
   sets, and the colour is stated per surface: the icon tiles are pale in
   daylight and dark at night, so a single fixed colour would vanish in one
   of them. */
.gi{width:1em;height:1em;display:block;flex:0 0 auto}
.ic .gi{width:.86em;height:.86em;color:#EFFFF7}
:root[data-theme="day"] .ic .gi{color:#0E5B33}
.prog h3 .ic{vertical-align:middle}

/* icon + label on one line: card meta, event details */
.ln{display:inline-flex;align-items:center;gap:6px}
.ln .gi{width:1.08em;height:1.08em;opacity:.85}

.pub-blank b{display:grid;place-items:center}
.pub-blank b .gi{width:1.5rem;height:1.5rem}
.pub-zoom{display:grid;place-items:center}
.pub-zoom .gi{width:17px;height:17px}
.quiz-open .qo-ic,.quiz-wait .qw-ic{display:grid;place-items:center;justify-content:center}
.quiz-open .qo-ic .gi,.quiz-wait .qw-ic .gi{width:2.2rem;height:2.2rem;margin-inline:auto;
  color:#63FFCE}
:root[data-theme="day"] .stage .qo-ic .gi,
:root[data-theme="day"] .stage .qw-ic .gi{color:#127038}

/* the four step numerals on the app page, formerly keycap emoji */
.feat .fic{font-family:var(--f-lat);font-size:1.45rem;font-weight:800;
  color:#63FFCE;letter-spacing:0}
:root[data-theme="day"] .feat .fic{color:#127038}

/* the lightbox and popup close buttons */
.lb-x .gi,.promo-x .gi{width:20px;height:20px;margin:auto}

/* a tip line that used to open with 💡 */
.quiz-tip .gi{display:inline-block;vertical-align:-.16em;margin-right:6px}

/* ── the app page's dark canvas must fall with the light, not before it ──
   /app puts an opaque <main class="stage"> over the sky. In daylight it is
   forced transparent, so the sun shows through; the instant the theme flipped
   the gradient came back at full strength and covered the whole sunset. The
   disc was still moving — measured travelling 77px to 826px — behind a solid
   panel.

   The alpha of the base layer is a registered custom property so it can be
   animated (a gradient cannot be transitioned). Where @property is not
   supported the declaration is dropped and the canvas simply arrives at the
   end of the scene, which is the old behaviour. */
@property --stgA{syntax:'<number>';inherits:false;initial-value:1}

@keyframes stageFall{0%{--stgA:0}42%{--stgA:.2}72%{--stgA:.58}100%{--stgA:1}}
@keyframes stageRise{0%{--stgA:1}30%{--stgA:.5}64%{--stgA:.16}100%{--stgA:0}}

:root.to-night .stage,:root.to-day .stage{
  background:
    radial-gradient(90% 70% at 18% 4%,rgba(47,184,119,.28) 0%,transparent 58%),
    radial-gradient(80% 66% at 88% 14%,rgba(98,71,196,.34) 0%,transparent 58%),
    radial-gradient(96% 74% at 50% 108%,rgba(27,111,168,.34) 0%,transparent 60%),
    linear-gradient(168deg,rgba(7,12,28,var(--stgA)) 0%,rgba(11,20,48,var(--stgA)) 46%,
      rgba(10,16,38,var(--stgA)) 100%)!important}
:root.to-night .stage{animation:stageFall 2.7s cubic-bezier(.5,.05,.7,.62) both}
:root.to-day   .stage{animation:stageRise 2.5s cubic-bezier(.3,.4,.5,1) both}

/* its two decorative sheets come and go on the same beat instead of blinking */
:root.to-night .stage::before{display:block!important;
  animation:glowIn 2.7s ease-in both,orbit 60s linear infinite}
:root.to-day .stage::before{display:block!important;
  animation:glowOut 2.5s ease-out both,orbit 60s linear infinite}
:root.to-night .stage::after{display:block!important;animation:noiseIn 2.7s ease-in both}
:root.to-day .stage::after{display:block!important;animation:noiseOut 2.5s ease-out both}
@keyframes glowIn{0%{opacity:0}45%{opacity:.2}100%{opacity:1}}
@keyframes glowOut{0%{opacity:1}100%{opacity:0}}
@keyframes noiseIn{0%{opacity:0}100%{opacity:.05}}
@keyframes noiseOut{0%{opacity:.05}100%{opacity:0}}

/* the text on that canvas has to stay readable the whole way across, so it
   changes colour on the same curve rather than waiting for the ground */
:root.to-night .stage,:root.to-day .stage,
:root.to-night .stage .lead,:root.to-day .stage .lead{
  transition:color 1.5s ease .5s!important}

@media (prefers-reduced-motion:reduce){
  :root.to-night .stage,:root.to-day .stage,
  :root.to-night .stage::before,:root.to-day .stage::before,
  :root.to-night .stage::after,:root.to-day .stage::after{animation:none!important}
}

/* ═══ REDUCED MOTION — quieter, not switched off ═══════════════════
   Windows turns "animation effects" off by default on low-powered machines,
   in battery saver, and under a lot of school/office policies. That shows up
   as prefers-reduced-motion: reduce, and the blocks above answered it by
   killing everything — measured on such a machine: 124 running animations
   drop to 24, and the day/night switch becomes an instant jump.

   The guideline is about large, sweeping movement, not about all change. So
   the motion is kept and made small: the sun dips a little and fades instead
   of flying across the screen, the sky and the page still cross-fade, and the
   constant drifting particles stay off, because unending motion is the part
   that actually causes trouble. Everything reads, nothing sweeps. */
@media (prefers-reduced-motion:reduce){

  /* the switch still plays, in place */
  :root.to-night .daystar,:root.to-day .daystar{
    animation:none!important;transition:top .7s ease,opacity .7s ease,filter .7s ease!important}
  :root[data-theme="night"] .daystar{top:22%;opacity:0;transform:translateX(-4vw) scale(1.12)}
  :root[data-theme="day"]   .daystar{top:3%;opacity:1;transform:translateX(0) scale(1)}

  /* the warm band still washes through — it is opacity only */
  :root.to-night .sky::after{animation:dusk .9s ease-out both!important}
  :root.to-day   .sky::after{animation:dawn .9s ease-out both!important}

  /* sky, page and the app canvas still change colour, just briskly */
  .sky,body{transition:background .8s ease,background-color .8s ease!important}
  :root[data-theme="night"] .sky,:root[data-theme="night"] body{
    transition:background .8s ease,background-color .8s ease!important}
  :root.to-night .stage,:root.to-day .stage{animation-duration:.8s!important}
  :root.to-night .stage::before,:root.to-day .stage::before,
  :root.to-night .stage::after,:root.to-day .stage::after{animation-duration:.8s!important}

  /* the globe keeps turning: it is slow, small and never sweeps the screen */
  .heroX .globe .land{animation:spinmap 72s linear infinite!important}

  /* a reveal is a fade, with no travel */
  .rv{transition:opacity .45s ease!important;transform:none!important}

  /* what stays off: anything that never stops moving */
  .drift,.lv .l,.aurora i,.streak,.daystar::after{animation:none!important}
}

/* ── the leaves keep drifting on a reduced-motion machine ───────────
   Switching them off with the rest was too blunt: the leaves are the one
   piece of motion that carries the brand, and they are slow and small
   already. They stay, at two-thirds speed, while the fast shooting streaks
   and the constant particle drift remain off. */
@media (prefers-reduced-motion:reduce){
  .lv .l{animation:lvFloat 27s ease-in-out infinite!important}
  .aurora i{animation-duration:40s!important}
}

/* ── daytime treeline ───────────────────────────────────────────────
   The silhouettes are painted #0C1E38 / #071426, and daylight inverted them
   to a pale wash that vanished against a bright sky. Inverting is the wrong
   move: a real horizon of trees reads *darker* than the sky behind it, not
   lighter. So the artwork keeps its shape and is tinted green instead — the
   far ridge hazier and bluer, the near one solid, the way distance works. */
:root[data-theme="day"] .woods{opacity:1}
:root[data-theme="day"] .woods .far{
  filter:invert(58%) sepia(24%) saturate(680%) hue-rotate(94deg) brightness(84%) contrast(88%);
  opacity:.42}
:root[data-theme="day"] .woods .near{
  filter:invert(34%) sepia(38%) saturate(560%) hue-rotate(96deg) brightness(62%) contrast(96%);
  opacity:.72}
/* the home hero's own treeline, on the pages that carry one */
:root[data-theme="day"] .treeline .far{fill:#7FBF86;opacity:.5}
:root[data-theme="day"] .treeline .near{fill:#2F8B4E;opacity:.72}

/* ═══ A ROUNDER EARTH, A REAL ORBIT, A BETTER MOON ═════════════════

   1. The globe read flat because the shading was too gentle to suggest
      curvature. A sphere's strongest visual cue is limb darkening — the
      edge falling away from the viewer — together with one bright shoulder
      where the light lands and a terminator opposite it. All three are
      strengthened below.
   2. The ring was a plain hairline circle floating around a globe whose moon
      travels an ellipse. Now the ring *is* that ellipse: same 172x112 radii
      the moon uses, with its far half dim and its near half bright, drawn in
      front of the planet — so the ring and the moon describe one orbit.
   3. The moon gains a terminator lit from the same direction as the earth,
      plus finer crater detail. */

/* ── 1. the sphere ─────────────────────────────────────────────── */
.heroX .globe .shade{background:
  /* specular glint where the sun strikes the atmosphere */
  radial-gradient(circle at 29% 23%,rgba(255,255,255,.40) 0%,rgba(255,255,255,.13) 17%,transparent 40%),
  /* the broad lit shoulder */
  radial-gradient(circle at 34% 30%,rgba(196,228,255,.22) 0%,transparent 54%),
  /* terminator — the night side, falling away to the lower right */
  radial-gradient(circle at 90% 88%,rgba(0,6,22,.70) 0%,rgba(0,6,22,.38) 30%,
    rgba(0,8,26,.12) 58%,transparent 78%),
  /* limb darkening — the curve of the planet turning away from us */
  radial-gradient(circle at 50% 50%,transparent 50%,rgba(0,6,20,.14) 72%,
    rgba(0,5,18,.46) 89%,rgba(0,4,14,.74) 100%)
  !important}
:root[data-theme="day"] .heroX .globe .shade{background:
  radial-gradient(circle at 27% 21%,rgba(255,255,255,.62) 0%,rgba(255,255,255,.20) 18%,transparent 42%),
  radial-gradient(circle at 33% 28%,rgba(255,252,235,.26) 0%,transparent 52%),
  radial-gradient(circle at 90% 88%,rgba(12,46,80,.42) 0%,rgba(12,46,80,.20) 32%,transparent 70%),
  radial-gradient(circle at 50% 50%,transparent 54%,rgba(10,40,72,.10) 74%,
    rgba(10,38,68,.30) 90%,rgba(8,32,60,.52) 100%)
  !important}

/* the atmosphere: a bright crescent on the sunward limb, dark on the far one */
.heroX .globe::after{box-shadow:
  inset 0 0 26px 3px rgba(150,215,255,.26),
  inset 15px 15px 32px -13px rgba(214,242,255,.60),
  inset -22px -22px 46px -15px rgba(0,8,28,.74)!important}
:root[data-theme="day"] .heroX .globe::after{box-shadow:
  inset 0 0 30px 3px rgba(255,250,225,.44),
  inset 17px 17px 38px -12px rgba(255,255,255,.72),
  inset -20px -20px 42px -14px rgba(16,54,92,.40)!important}

/* the halo sitting just outside the disc, brighter where the light comes from */
.heroX .atmo{box-shadow:
  0 0 54px 8px rgba(120,205,255,.30),
  0 0 150px 44px rgba(56,140,225,.20),
  inset 0 0 0 1px rgba(170,225,255,.10)!important}

/* ── 2. the orbit ──────────────────────────────────────────────── */
/* The elliptical orbit ring was reverted at the client's request; the thin
   circle defined earlier in this file stands. The moon keeps its original
   path and its improved surface. */

/* ── 3. the moon ───────────────────────────────────────────────── */
.moon i{
  background:
    radial-gradient(circle at 33% 28%,#FBF8F1 0%,#E4DED2 32%,#B8B2A6 62%,#6E695F 100%)!important;
  box-shadow:
    inset -5px -4px 9px rgba(14,14,20,.62),
    inset 2px 2px 5px rgba(255,255,255,.28),
    0 0 16px rgba(226,230,244,.30)!important}
/* craters, finer and lit from the same side as the earth */
.moon i::after{opacity:.62!important;background:
  radial-gradient(circle at 31% 60%,rgba(96,92,86,.85) 0 12%,transparent 14%),
  radial-gradient(circle at 62% 32%,rgba(96,92,86,.72) 0 8%,transparent 10%),
  radial-gradient(circle at 72% 66%,rgba(96,92,86,.62) 0 6%,transparent 8%),
  radial-gradient(circle at 45% 20%,rgba(96,92,86,.55) 0 4.5%,transparent 6%),
  radial-gradient(circle at 24% 38%,rgba(96,92,86,.45) 0 3.5%,transparent 5%),
  radial-gradient(circle at 55% 78%,rgba(96,92,86,.40) 0 3%,transparent 4.5%),
  /* the moon's own terminator */
  radial-gradient(circle at 76% 80%,rgba(10,10,16,.50) 0%,transparent 62%)!important}

/* ═══ HEADER AND THE PILL BENEATH IT ═══════════════════════════════

   The hero centres its content vertically, so on a tall window there is
   plenty of room under the floating bar — but its top padding was
   clamp(96px,12vh,140px) while the bar itself reaches 93px down the page.
   On a shorter window the centred block bottoms out against that padding and
   the pill ends up a few pixels under the bar. The padding now clears the
   bar with room to spare at every height. */
.heroX{padding-top:clamp(134px,15vh,172px)!important}

/* a slimmer bar: the same contents, less air above and below */
.head{padding-top:10px!important;padding-bottom:10px!important}
.head .brand .bmark{width:clamp(34px,3.4vw,40px)}
.nav a{padding-top:8px;padding-bottom:8px}
.tgl{width:38px;height:38px}

/* and 20% more transparent glass */
.head::after{
  background:linear-gradient(180deg,rgba(20,40,64,.46),rgba(10,24,42,.38))}
:root[data-theme="day"] .head::after{
  background:linear-gradient(180deg,rgba(255,255,255,.54),rgba(255,255,255,.38))}

@media (max-width:900px){
  .heroX{padding-top:clamp(118px,14vh,150px)!important}
}

/* ═══ MOBILE HEADER AND TREELINE FIXES ═════════════════════════════

   1. The theme toggle and burger were bunched against the logo with the
      whole right half of the bar empty. Cause: .nav carries
      margin-left:auto;margin-right:auto to centre itself, but below 1020px
      style.css turns .nav into a position:fixed drawer — it leaves the flex
      flow entirely, and its auto margins go with it. .brand and .hactions
      were then the only in-flow children, with nothing pushing them apart.
      Restoring an auto margin on .hactions puts them back on the right. */
@media (max-width:1020px){
  .head .hactions{margin-left:auto}
}

/* 2. The treeline sits at the foot of the fixed sky layer, so on a phone it
      lands exactly where the hero's lead paragraph and buttons are —
      measured at 390x844: woods 591-844, lead 665-723, buttons 745-882.
      In daylight the ridges are now solid green, so dark text over them lost
      its contrast. Two changes: the band is shorter on small screens, and
      its top edge dissolves into the sky instead of ending in a hard sawtooth
      across the middle of a sentence. */
.woods{
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 36%);
  mask-image:linear-gradient(180deg,transparent 0,#000 36%)}
@media (max-width:900px){
  .woods{height:min(20vh,170px)}
  :root[data-theme="day"] .woods .near{opacity:.62}
  :root[data-theme="day"] .woods .far{opacity:.34}
}

/* …and on a phone the treeline goes away completely.

   Shortening it, fading its top edge and dropping its opacity all helped and
   none of them fixed it, because the collision is structural rather than a
   matter of degree. .woods is anchored to the bottom of .sky, which is
   position:fixed — so it is pinned to the bottom of the *viewport*, not to the
   bottom of the hero. The hero on a phone is taller than the screen, so its
   closing paragraph and buttons are still on screen at the bottom when the
   trees are drawn there. Whatever height the band is given, the text is
   inside it.

   There is no arrangement that keeps a viewport-pinned decoration and
   readable copy in the same place, so the copy wins. The trees remain on
   tablets and desktops, where the hero fits above them. */
@media (max-width:760px){
  .woods{display:none!important}
}

/* 3. …and the hero copy is lifted clear of whatever is behind it. */
@media (max-width:900px){
  .heroX .hx-copy .lead{
    text-shadow:0 1px 2px rgba(255,255,255,.55)}
  :root[data-theme="night"] .heroX .hx-copy .lead{
    text-shadow:0 1px 3px rgba(2,10,24,.65)}
}

/* ═══ WHAT YOU SEE WHILE SCROLLING ═══════════════════════════════════

   A. The bar let the page read straight through it.

      .head::after asks for backdrop-filter:blur(22px), but that blur never
      reaches the screen — captured on the live site at 1440x900, a card
      heading and a phone-number button sliding under the bar stayed
      perfectly crisp. So the only thing actually concealing the page was the
      tint, and the transparency pass thinned it to .54/.38. Card text became
      legible through the glass.

      Two things follow. The blur is deleted rather than repaired: a fixed
      element with a backdrop-filter has to re-read and re-rasterise the
      pixels behind it on every frame of a scroll, which is the single most
      expensive thing on a cheap phone, and here it was buying nothing. And
      the tint now does the job properly — but only once the page is actually
      moving. Over the hero there is nothing to hide, so the bar keeps the
      airy glass; from the first scroll step (.stuck, y>20) it thickens.

      A first pass took the tint to .95/.91 and it was not enough: a bold
      heading passing underneath still ghosted through at 5% as legible grey
      letters. Scrolled, the bar is now opaque outright. Nothing is lost —
      the translucency only ever mattered over the hero, and at the top of
      the page (no .stuck) the glass is untouched. */
.head::after{backdrop-filter:none!important;-webkit-backdrop-filter:none!important}
.head.stuck::after{
  background:linear-gradient(180deg,#101F35,#0A1626);
  border-color:rgba(255,255,255,.16)}
:root[data-theme="day"] .head.stuck::after{
  background:linear-gradient(180deg,#FFFFFF,#F4F9FC);
  border-color:rgba(214,232,242,.95);
  box-shadow:0 14px 38px -20px rgba(30,80,120,.30),inset 0 1px 0 #fff}

/* B. The hero's props stopped following the reader down the page.

      .sky is one position:fixed sheet behind the entire document, so the
      sun, the treeline and the light streaks stayed on screen for all 6,291
      pixels of the home page. On a wide screen that reads as a deliberate
      outdoor backdrop. On a 361px phone the sun is a quarter of the viewport
      and the trees own the bottom third, so they turned up behind the quiz
      copy and the channel cards looking like a rendering fault.

      app.js sets .past-hero once the hero has left the screen. The gradient
      stays — it is the page's background — and only the props retire.
      Pausing them as well as fading them takes their animations off the
      compositor for the rest of the scroll instead of running them at zero
      alpha. Leaves stay: they are ambient rather than scenery.

      The !important below is not decoration. The sun is pinned by
      `.daystar{opacity:1!important}` up in the sun block, and an author
      !important outranks any later rule no matter how specific — measured
      after the first attempt: .woods went to 0, .daystar stayed at 1. */
@media (max-width:900px){
  .daystar,.woods,.streak,.aurora{transition:opacity .5s var(--e-soft)}
  :root.past-hero .daystar,
  :root.past-hero .woods,
  :root.past-hero .streak{opacity:0!important;animation-play-state:paused}
  :root.past-hero .daystar::after{animation-play-state:paused}
  :root.past-hero .aurora{opacity:.38}
  :root.past-hero .aurora i{animation-play-state:paused}
}

/* C. The app teaser is three phone mock-ups under filter:blur(13px) with a
      backdrop-filter:blur(26px) veil on top — two stacked blurs, one of them
      re-sampled on every scroll frame. Below 900px style.css already drops
      two of the three phones, which leaves the remaining one reading as a
      cyan smear rather than a device. Lighter blur, calmer colour, and the
      veil switches to a plain tint so nothing is re-sampled during a scroll. */
@media (max-width:900px){
  .dblur{filter:blur(9px) saturate(1.15);opacity:.55}
  .veil{backdrop-filter:none!important;-webkit-backdrop-filter:none!important;
    background:linear-gradient(180deg,rgba(10,22,42,.72),rgba(8,18,36,.82))}
  :root[data-theme="day"] .veil{
    background:linear-gradient(180deg,rgba(12,26,48,.78),rgba(9,20,38,.86))}
}

/* ── a hovered box must not be sliced by its own section ─────────────
   .stat lifts 7px when hovered (translate3d(0,-7px,0)), and every .sec
   carries content-visibility:auto for the scrolling win. That property brings
   paint containment with it: anything drawn outside the section's own box is
   cut away. The statistics section was written with padding-top:0, so the
   boxes sat flush against that edge and the lift was sliced clean off —
   measured on the live site, TOP cut 7px on every card, desktop and phone.

   The first attempt padded the section and pulled it back up with an equal
   negative margin. It stopped the clipping and it moved nothing on screen,
   but it left the hero and this section genuinely overlapping by 16px —
   measured at three widths — which is a worse problem than the one it solved.

   So remove the cause instead of making room around it: this one section opts
   out of content-visibility, and with no paint containment there is nothing
   to clip the lift. It costs the skip-rendering optimisation on a strip of
   five small cards, which is not a measurable amount of work, and the section
   keeps the padding-top:0 the design asks for.

   Anything else that lifts on hover sits inside a section with the normal
   clamp(72px,9vw,132px) of padding — far more headroom than these transforms
   need — so this stays a one-section exception. */
#intro{padding-top:0;content-visibility:visible;contain-intrinsic-size:auto}

/* The quiz map positions its region names from each shape's own box, which
   reads as zero while content-visibility is skipping the section's layout.
   .sec:not(.hero):not(.heroX) above is (0,3,0), so this has to match it —
   a plain .qsec loses no matter which file it sits in. */
.qsec:not(.hero):not(.heroX){content-visibility:visible;contain-intrinsic-size:auto}
